Update component docs

- Relates #361
This commit is contained in:
Janne Valkealahti
2022-02-24 09:25:38 +00:00
parent 4733c3c7b5
commit 8920db699d
12 changed files with 576 additions and 0 deletions

View File

@@ -0,0 +1,23 @@
Some info how screen recordings were made
asciinema rec spring-shell-docs/src/main/asciidoc/asciinema/component-text-input-1.cast
asciinema rec spring-shell-docs/src/main/asciidoc/asciinema/component-path-input-1.cast
asciinema rec spring-shell-docs/src/main/asciidoc/asciinema/component-confirmation-1.cast
asciinema rec spring-shell-docs/src/main/asciidoc/asciinema/component-single-select-1.cast
asciinema rec spring-shell-docs/src/main/asciidoc/asciinema/component-multi-select-1.cast
svg-term \
--in spring-shell-docs/src/main/asciidoc/asciinema/component-text-input-1.cast \
--out spring-shell-docs/src/main/asciidoc/images/component-text-input-1.svg
svg-term \
--in spring-shell-docs/src/main/asciidoc/asciinema/component-path-input-1.cast \
--out spring-shell-docs/src/main/asciidoc/images/component-path-input-1.svg
svg-term \
--in spring-shell-docs/src/main/asciidoc/asciinema/component-confirmation-1.cast \
--out spring-shell-docs/src/main/asciidoc/images/component-confirmation-1.svg
svg-term \
--in spring-shell-docs/src/main/asciidoc/asciinema/component-single-select-1.cast \
--out spring-shell-docs/src/main/asciidoc/images/component-single-select-1.svg
svg-term \
--in spring-shell-docs/src/main/asciidoc/asciinema/component-multi-select-1.cast \
--out spring-shell-docs/src/main/asciidoc/images/component-multi-select-1.svg

View File

@@ -0,0 +1,35 @@
{"version": 2, "width": 85, "height": 8, "timestamp": 1645645867, "env": {"SHELL": "/bin/bash", "TERM": "xterm-256color"}}
[1.590847, "o", "java -jar spring-shell-samples/target/spring-shell-samples-2.1.0-SNAPSHOT.jar"]
[2.774407, "o", "\r\n"]
[4.560309, "o", "\u001b[?1h\u001b=\u001b[?2004h\u001b[33mmy-shell:>\u001b[0m"]
[5.138757, "o", "\u001b[31mc\u001b[0m"]
[5.267214, "o", "\u001b[31mo\u001b[0m"]
[5.467126, "o", "\u001b[31mm\u001b[0m"]
[5.674049, "o", "\u001b[31mp\u001b[0m"]
[5.752663, "o", "\u001b[31mo\u001b[0m"]
[5.917741, "o", "\u001b[31mn\u001b[0m"]
[6.040844, "o", "\u001b[31me\u001b[0m"]
[6.123068, "o", "\u001b[31mn\u001b[0m"]
[6.277935, "o", "\u001b[31mt\u001b[0m"]
[7.050283, "o", "\u001b[31m \u001b[0m"]
[7.413917, "o", "\u001b[31mc\u001b[0m"]
[7.568894, "o", "\u001b[31mo\u001b[0m"]
[7.664856, "o", "\u001b[31mn\u001b[0m"]
[7.853492, "o", "\u001b[13D\u001b[1mcomponent confirmation\u001b[0m \u001b[K"]
[8.698242, "o", "\r\r\n\u001b[?1l\u001b>\u001b[?1000l\u001b[?2004l"]
[8.745928, "o", "\u001b[?1h\u001b=\u001b[?25l"]
[8.803411, "o", "\u001b[32;1m?\u001b[0m \u001b[97;1mEnter value\u001b[0m \u001b[2m(Y/n)\u001b[0m\r"]
[13.769588, "o", "\u001b[?1l\u001b>\u001b[?12;25h\u001b[K"]
[13.779021, "o", "\u001b[32;1m?\u001b[0m \u001b[97;1mEnter value\u001b[0m \u001b[34mtrue\u001b[0m\r\n"]
[13.779319, "o", "Got value true\r\n"]
[13.781245, "o", "\u001b[?1h\u001b=\u001b[?2004h\u001b[33mmy-shell:>\u001b[0m"]
[15.955396, "o", "\u001b[1mcomponent confirmation\u001b[0m"]
[16.743244, "o", "\r\r\n\u001b[?1l\u001b>\u001b[?1000l"]
[16.743555, "o", "\u001b[?2004l"]
[16.748638, "o", "\u001b[?1h\u001b=\u001b[?25l"]
[16.754861, "o", "\u001b[32;1m?\u001b[0m \u001b[97;1mEnter value\u001b[0m \u001b[2m(Y/n)\u001b[0m\r"]
[19.347907, "o", "\u001b[?1l\u001b>\u001b[?12;25h\u001b[K"]
[19.355493, "o", "\u001b[32;1m?\u001b[0m \u001b[97;1mEnter value\u001b[0m \u001b[34mfalse\u001b[0m\r\n"]
[19.356618, "o", "Got value false\r\n"]
[19.3586, "o", "\u001b[?1h\u001b=\u001b[?2004h\u001b[33mmy-shell:>\u001b[0m"]
[21.3586, "o", "\u001b[?1h\u001b=\u001b[?2004h\u001b[33mmy-shell:>\u001b[0m"]

View File

@@ -0,0 +1,42 @@
{"version": 2, "width": 85, "height": 9, "timestamp": 1645645867, "env": {"SHELL": "/bin/bash", "TERM": "xterm-256color"}}
[1.746447, "o", "java -jar spring-shell-samples/target/spring-shell-samples-2.1.0-SNAPSHOT.jar"]
[2.881033, "o", "\r\n"]
[4.603396, "o", "\u001b[?1h\u001b=\u001b[?2004h\u001b[33mmy-shell:>\u001b[0m"]
[5.105471, "o", "\u001b[31mc\u001b[0m"]
[5.202878, "o", "\u001b[31mo\u001b[0m"]
[5.428705, "o", "\u001b[31mm\u001b[0m"]
[5.630033, "o", "\u001b[31mp\u001b[0m"]
[5.692044, "o", "\u001b[31mo\u001b[0m"]
[5.86652, "o", "\u001b[31mn\u001b[0m"]
[6.018765, "o", "\u001b[31me\u001b[0m"]
[6.089776, "o", "\u001b[31mn\u001b[0m"]
[6.251781, "o", "\u001b[31mt\u001b[0m"]
[7.126694, "o", "\u001b[31m \u001b[0m"]
[7.319912, "o", "\u001b[31mm\u001b[0m"]
[7.550772, "o", "\u001b[31mu\u001b[0m"]
[7.80087, "o", "\u001b[12D\u001b[1mcomponent multi\u001b[0m \u001b[K"]
[8.291497, "o", "\r\r\n\u001b[?1l\u001b>\u001b[?1000l\u001b[?2004l"]
[8.338879, "o", "\u001b[?1h\u001b=\u001b[?25l"]
[8.398742, "o", "\u001b[32;1m?\u001b[0m \u001b[97;1mtestSimple\u001b[0m [Use arrows to move], type to filter\u001b[54C \u001b[96;1m>\u001b[0m\u001b[96;1m \u001b[39m[ ]\u001b[0m key1\u001b[93C \u001b[2m[ ]\u001b[0m \u001b[2mkey2\u001b[0m\u001b[93C \u001b[1m[ ]\u001b[0m key3\u001b[3A\r"]
[12.265649, "o", "\u001b[35Cfiltering 'k'\u001b[K\r"]
[12.507991, "o", "\u001b[47C\u001b[1@e\r"]
[12.945812, "o", "\u001b[48C\u001b[1@y\r"]
[13.35949, "o", "\u001b[49C\u001b[1@1\r\r\n\u001b[103C \u001b[K\r\r\r\n\u001b[K\r\r\n\u001b[K\u001b[3A"]
[14.187299, "o", "\u001b[49C\u001b[P\r\r\n\u001b[103C \u001b[2m[ ]\u001b[0m \u001b[2mkey2\u001b[0m\u001b[93C \u001b[1m[ ]\u001b[0m key3\u001b[3A\r"]
[14.356992, "o", "\u001b[48C\u001b[P\r"]
[14.495579, "o", "\u001b[47C\u001b[P\r"]
[14.642467, "o", "\u001b[35Ctype to filter\u001b[K\r"]
[15.763904, "o", "\r\r\n\u001b[2C\u001b[32m[x]\u001b[0m\u001b[A\r"]
[16.496138, "o", "\r\r\n \r\r\n\u001b[96;1m> \u001b[0m\u001b[2A\r"]
[16.678991, "o", "\r\r\n\r\n \r\r\n\u001b[96;1m> \u001b[0m\u001b[3A\r"]
[17.979077, "o", "\r\r\n\r\n\r\n\u001b[2C\u001b[32m[x]\u001b[0m\u001b[3A\r"]
[18.809587, "o", "\r\r\n\r\n\r\n\u001b[2C\u001b[1m[ ]\u001b[0m\u001b[3A\r"]
[20.452942, "o", "\r\r\n\r\n\u001b[96;1m> \u001b[0m\r\r\n \u001b[3A\r"]
[21.705426, "o", "\r\r\n\r\n \r\r\n\u001b[96;1m> \u001b[0m\u001b[3A\r"]
[22.207898, "o", "\r\r\n\r\n\r\n\u001b[2C\u001b[32m[x]\u001b[0m\u001b[3A\r"]
[23.30633, "o", "\r\r\n\r\n\r\n\u001b[2C\u001b[1m[ ]\u001b[0m\u001b[3A\r"]
[24.642701, "o", "\u001b[?1l\u001b>\u001b[?12;25h\u001b[K\r\r\n\u001b[K\r\r\n\u001b[K\r\r\n\u001b[K\u001b[3A"]
[24.64692, "o", "\u001b[32;1m?\u001b[0m \u001b[97;1mtestSimple\u001b[0m \u001b[34mvalue1\u001b[0m\r\n"]
[24.647546, "o", "Got value value1\r\n"]
[24.649365, "o", "\u001b[?1h\u001b=\u001b[?2004h\u001b[33mmy-shell:>\u001b[0m"]
[26.649365, "o", "\u001b[?1h\u001b=\u001b[?2004h\u001b[33mmy-shell:>\u001b[0m"]

View File

@@ -0,0 +1,35 @@
{"version": 2, "width": 85, "height": 6, "timestamp": 1645645867, "env": {"SHELL": "/bin/bash", "TERM": "xterm-256color"}}
[1.276071, "o", "java -jar spring-shell-samples/target/spring-shell-samples-2.1.0-SNAPSHOT.jar"]
[1.975169, "o", "\r\n"]
[3.730642, "o", "\u001b[?1h\u001b=\u001b[?2004h\u001b[33mmy-shell:>\u001b[0m"]
[4.157171, "o", "\u001b[31mc\u001b[0m"]
[4.259876, "o", "\u001b[31mo\u001b[0m"]
[4.480644, "o", "\u001b[31mm\u001b[0m"]
[4.675743, "o", "\u001b[31mp\u001b[0m"]
[4.746389, "o", "\u001b[31mo\u001b[0m"]
[4.899817, "o", "\u001b[31mn\u001b[0m"]
[5.064803, "o", "\u001b[31me\u001b[0m"]
[5.151957, "o", "\u001b[31mn\u001b[0m"]
[5.295573, "o", "\u001b[31mt\u001b[0m"]
[5.626209, "o", "\u001b[31m \u001b[0m"]
[5.949778, "o", "\u001b[31mp\u001b[0m"]
[6.052068, "o", "\u001b[31ma\u001b[0m"]
[6.270888, "o", "\u001b[31mt\u001b[0m"]
[6.342701, "o", "\u001b[13D\u001b[1mcomponent path\u001b[0m\u001b[K"]
[6.866598, "o", "\r\r\n\u001b[?1l\u001b>\u001b[?1000l\u001b[?2004l"]
[6.918336, "o", "\u001b[?1h\u001b=\u001b[?25l"]
[6.979593, "o", "\u001b[32;1m?\u001b[0m \u001b[97;1mEnter value\u001b[0m \r"]
[8.74751, "o", "\u001b[14C/\u001b[88C \u001b[31m>\u001b[0m\u001b[31m>>\u001b[0m \u001b[31mDirectory exists\u001b[0m\u001b[A\r"]
[10.825765, "o", "\u001b[15Ct\r\r\n\u001b[32m>\u001b[0m \u001b[32mPath ok\u001b[0m\u001b[K\u001b[A\r"]
[10.96141, "o", "\u001b[16Cm\r"]
[11.050615, "o", "\u001b[17Cp\r\r\n\u001b[31m>>>\u001b[0m \u001b[31mDirectory exists\u001b[0m\u001b[K\u001b[A\r"]
[11.812886, "o", "\u001b[18C/\r"]
[11.930461, "o", "\u001b[19Cd\r\r\n\u001b[32m>\u001b[0m \u001b[32mPath ok\u001b[0m\u001b[K\u001b[A\r"]
[12.128981, "o", "\u001b[20Ce\r"]
[12.176119, "o", "\u001b[21Cm\r"]
[12.28765, "o", "\u001b[22Co\r"]
[13.464196, "o", "\u001b[?1l\u001b>\u001b[?12;25h\u001b[K\r\r\n\u001b[K\u001b[A"]
[13.471408, "o", "\u001b[32;1m?\u001b[0m \u001b[97;1mEnter value\u001b[0m \u001b[34m/tmp/demo\u001b[0m\r\n"]
[13.471875, "o", "Got value /tmp/demo\r\n"]
[13.475016, "o", "\u001b[?1h\u001b=\u001b[?2004h\u001b[33mmy-shell:>\u001b[0m"]
[15.475016, "o", "\u001b[?1h\u001b=\u001b[?2004h\u001b[33mmy-shell:>\u001b[0m"]

View File

@@ -0,0 +1,38 @@
{"version": 2, "width": 85, "height": 8, "timestamp": 1645645867, "env": {"SHELL": "/bin/bash", "TERM": "xterm-256color"}}
[2.193321, "o", "java -jar spring-shell-samples/target/spring-shell-samples-2.1.0-SNAPSHOT.jar"]
[3.11524, "o", "\r\n"]
[4.904714, "o", "\u001b[?1h\u001b=\u001b[?2004h\u001b[33mmy-shell:>\u001b[0m"]
[5.372714, "o", "\u001b[31mc\u001b[0m"]
[5.484943, "o", "\u001b[31mo\u001b[0m"]
[5.70511, "o", "\u001b[31mm\u001b[0m"]
[5.913092, "o", "\u001b[31mp\u001b[0m"]
[5.992808, "o", "\u001b[31mo\u001b[0m"]
[6.159092, "o", "\u001b[31mn\u001b[0m"]
[6.281094, "o", "\u001b[31me\u001b[0m"]
[6.353925, "o", "\u001b[31mn\u001b[0m"]
[6.49373, "o", "\u001b[31mt\u001b[0m"]
[6.677988, "o", "\u001b[31m \u001b[0m"]
[6.825018, "o", "\u001b[31ms\u001b[0m"]
[6.95602, "o", "\u001b[31mi\u001b[0m"]
[7.121719, "o", "\u001b[31mn\u001b[0m"]
[7.309007, "o", "\u001b[13D\u001b[1mcomponent single\u001b[0m \u001b[K"]
[7.972392, "o", "\r\r\n\u001b[?1l\u001b>\u001b[?1000l\u001b[?2004l"]
[8.019885, "o", "\u001b[?1h\u001b=\u001b[?25l"]
[8.080156, "o", "\u001b[32;1m?\u001b[0m \u001b[97;1mtestSimple\u001b[0m [Use arrows to move], type to filter\u001b[54C \u001b[96;1m>\u001b[0m\u001b[96;1m key1\u001b[0m\u001b[97C key2\u001b[2A\r"]
[9.181662, "o", "\r\r\n key1\r\r\n\u001b[96;1m> key2\u001b[0m\u001b[2A\r"]
[9.701431, "o", "\r\r\n\u001b[96;1m> key1\u001b[0m\r\r\n key2\u001b[2A\r"]
[10.380557, "o", "\r\r\n key1\r\r\n\u001b[96;1m> key2\u001b[0m\u001b[2A\r"]
[12.157001, "o", "\u001b[35Cfiltering 'k'\u001b[K\r"]
[14.605973, "o", "\u001b[47C\u001b[1@e\r\r\n\u001b[96;1m> key1\u001b[0m\r\r\n key2\u001b[2A\r"]
[14.92268, "o", "\u001b[48C\u001b[1@y\r"]
[15.320008, "o", "\u001b[49C\u001b[1@1\r\r\n\u001b[103C \u001b[K\r\r\r\n\u001b[K\u001b[2A"]
[16.215448, "o", "\u001b[49C\u001b[P\r\r\n\u001b[103C key2\u001b[2A\r"]
[16.559377, "o", "\u001b[48C\u001b[P\r"]
[16.784486, "o", "\u001b[47C\u001b[P\r"]
[17.004921, "o", "\u001b[35Ctype to filter\u001b[K\r"]
[17.790542, "o", "\r\r\n key1\r\r\n\u001b[96;1m> key2\u001b[0m\u001b[2A\r"]
[18.340142, "o", "\u001b[?1l\u001b>\u001b[?12;25h\u001b[K\r\r\n\u001b[K\r\r\n\u001b[K\u001b[2A"]
[18.347511, "o", "\u001b[32;1m?\u001b[0m \u001b[97;1mtestSimple\u001b[0m \u001b[34mvalue2\u001b[0m\r\n"]
[18.34852, "o", "Got value value2\r\n"]
[18.35067, "o", "\u001b[?1h\u001b=\u001b[?2004h\u001b[33mmy-shell:>\u001b[0m"]
[20.35067, "o", "\u001b[?1h\u001b=\u001b[?2004h\u001b[33mmy-shell:>\u001b[0m"]

View File

@@ -0,0 +1,30 @@
{"version": 2, "width": 85, "height": 6, "timestamp": 1645645867, "env": {"SHELL": "/bin/bash", "TERM": "xterm-256color"}}
[1.262977, "o", "java -jar spring-shell-samples/target/spring-shell-samples-2.1.0-SNAPSHOT.jar"]
[2.045105, "o", "\r\n"]
[3.846992, "o", "\u001b[?1h\u001b=\u001b[?2004h\u001b[33mmy-shell:>\u001b[0m"]
[4.717927, "o", "\u001b[31mc\u001b[0m"]
[4.824399, "o", "\u001b[31mo\u001b[0m"]
[5.014061, "o", "\u001b[31mm\u001b[0m"]
[5.703137, "o", "\u001b[31mp\u001b[0m"]
[5.802386, "o", "\u001b[31mo\u001b[0m"]
[6.434988, "o", "\u001b[31mn\u001b[0m"]
[6.653321, "o", "\u001b[31me\u001b[0m"]
[6.756821, "o", "\u001b[31mn\u001b[0m"]
[7.293975, "o", "\u001b[31mt\u001b[0m"]
[7.409984, "o", "\u001b[31m \u001b[0m"]
[7.604973, "o", "\u001b[31ms\u001b[0m"]
[7.775599, "o", "\u001b[31mt\u001b[0m"]
[7.928792, "o", "\u001b[31mr\u001b[0m"]
[7.979401, "o", "\u001b[31mi\u001b[0m"]
[8.051232, "o", "\u001b[31mn\u001b[0m"]
[8.15451, "o", "\u001b[15D\u001b[1mcomponent string\u001b[0m\u001b[K"]
[8.892861, "o", "\r\r\n\u001b[?1l\u001b>\u001b[?1000l\u001b[?2004l"]
[8.951185, "o", "\u001b[?1h\u001b=\u001b[?25l"]
[9.013964, "o", "\u001b[32;1m?\u001b[0m \u001b[97;1mEnter value\u001b[0m \u001b[34m[Default myvalue]\u001b[0m\r"]
[10.304694, "o", "\u001b[14Ch\u001b[K\r"]
[10.533832, "o", "\u001b[15Ci\r"]
[11.088255, "o", "\u001b[?1l\u001b>\u001b[?12;25h\u001b[K"]
[11.097044, "o", "\u001b[32;1m?\u001b[0m \u001b[97;1mEnter value\u001b[0m \u001b[34mhi\u001b[0m\r\n"]
[11.097492, "o", "Got value hi\r\n"]
[11.100226, "o", "\u001b[?1h\u001b=\u001b[?2004h\u001b[33mmy-shell:>\u001b[0m"]
[13.100226, "o", "\u001b[?1h\u001b=\u001b[?2004h\u001b[33mmy-shell:>\u001b[0m"]

File diff suppressed because one or more lines are too long

After

Width:  |  Height:  |  Size: 10 KiB

File diff suppressed because one or more lines are too long

After

Width:  |  Height:  |  Size: 15 KiB

File diff suppressed because one or more lines are too long

After

Width:  |  Height:  |  Size: 11 KiB

File diff suppressed because one or more lines are too long

After

Width:  |  Height:  |  Size: 12 KiB

File diff suppressed because one or more lines are too long

After

Width:  |  Height:  |  Size: 8.5 KiB

View File

@@ -1024,6 +1024,374 @@ AttributedStyle style = themeResolver.resolveStyle(resolvedStyle);
----
====
[[uicomponents]]
=== UI Components
Starting from _2.1.x_ there is a new component model which provides
easier way to create higher level user interaction for usual use cases
like asking input in a various forms. These usually are just plain text
input or choosing something from a list.
Templates for build-in components are in classpath under
_org/springframework/shell/component_.
Build-in components generally follow logic:
* Enter run loop for user input
* Generate component related context
* Render runtime status of a component state
* Exit
* Render final status of a component state
==== Component Render
There are two ways to implement component rendering, firstly fully
programmatically or secondly using a _ANTLR Stringtemplate_. Though
strictly speaking there is just a simple `Function` renderer interface
which takes `Context` as an input and outputs a list of `AttributedString`
but this allows to choose between _templating_ and _code_.
Templating is a good choice if you don't need to anything complex or
you just want to slightly modify existing component layouts. Rendering
via code then gives you flexibility to do whatever you need.
Programmatic way to render is simple as to create a `Function`:
====
[source, java]
----
class StringInputCustomRenderer implements Function<StringInputContext, List<AttributedString>> {
@Override
public List<AttributedString> apply(StringInputContext context) {
AttributedStringBuilder builder = new AttributedStringBuilder();
builder.append(context.getName());
builder.append(" ");
if (context.getResultValue() != null) {
builder.append(context.getResultValue());
}
else {
String input = context.getInput();
if (StringUtils.hasText(input)) {
builder.append(input);
}
else {
builder.append("[Default " + context.getDefaultValue() + "]");
}
}
return Arrays.asList(builder.toAttributedString());
}
}
----
====
And then hook it with a component:
====
[source, java]
----
@ShellMethod(key = "component stringcustom", value = "String input", group = "Components")
public String stringInputCustom(boolean mask) {
StringInput component = new StringInput(getTerminal(), "Enter value", "myvalue",
new StringInputCustomRenderer());
component.setResourceLoader(getResourceLoader());
component.setTemplateExecutor(getTemplateExecutor());
if (mask) {
component.setMaskCharater('*');
}
StringInputContext context = component.run(StringInputContext.empty());
return "Got value " + context.getResultValue();
}
----
====
Component have their own context but usually shares some functionality
from a parent component types, those context variables are shown below.
[[textcomponentcontext-template-variables]]
.TextComponentContext Template Variables
|===
|Key |Description
|resultValue
|Value after component renders its result.
|name
|Name of a component, aka its title.
|message
|Possible message set for component.
|messageLevel
|Level of a message, either INFO, WARN or ERROR
|hasMessageLevelInfo
|Return true if level is INFO, false otherwise.
|hasMessageLevelWarn
|Return true if level is WARN, false otherwise.
|hasMessageLevelError
|Return true if level is ERROR, false otherwise.
|input
|Raw user input.
|===
[[selectorcomponentcontext-template-variables]]
.SelectorComponentContext Template Variables
|===
|Key |Description
|name
|Name of a component, aka title.
|input
|Raw user input, mostly for filter.
|itemStates
|Full list of item states.
|itemStateView
|Visible list of item states.
|isResult
|Return if context is in a result mode.
|cursorRow
|Current cursor row in a selector
|===
==== Build-in Components
===== String Input
Used to ask a simple text input from a user, optionally masking values
if content contains something sensitive.
====
[source, java]
----
@ShellComponent
public class ComponentCommands extends AbstractShellComponent {
@ShellMethod(key = "component string", value = "String input", group = "Components")
public String stringInput(boolean mask) {
StringInput component = new StringInput(getTerminal(), "Enter value", "myvalue");
component.setResourceLoader(getResourceLoader());
component.setTemplateExecutor(getTemplateExecutor());
if (mask) {
component.setMaskCharater('*');
}
StringInputContext context = component.run(StringInputContext.empty());
return "Got value " + context.getResultValue();
}
}
----
====
image::images/component-text-input-1.svg[text input]
Context object is `StringInputContext`.
[[stringinputcontext-template-variables]]
.StringInputContext Template Variables
|===
|Key |Description
|defaultValue
|Default value if set, null otherwise.
|maskedInput
|Masked input value
|maskedResultValue
|Masked result value
|maskCharacter
|Mask character if set, null otherwise.
|hasMaskCharacter
|Is true if mask character is set, false otherwise.
|model
|Parent context variables <<textcomponentcontext-template-variables>>
|===
===== Path Input
Used to ask a `Path` from a user and gives additional info about a path itself.
====
[source, java]
----
@ShellComponent
public class ComponentCommands extends AbstractShellComponent {
@ShellMethod(key = "component path", value = "Path input", group = "Components")
public String pathInput() {
PathInput component = new PathInput(getTerminal(), "Enter value");
component.setResourceLoader(getResourceLoader());
component.setTemplateExecutor(getTemplateExecutor());
PathInputContext context = component.run(PathInputContext.empty());
return "Got value " + context.getResultValue();
}
}
----
====
image::images/component-path-input-1.svg[text input]
Context object is `PathInputContext`.
[[pathinputcontext-template-variables]]
.PathInputContext Template Variables
|===
|Key |Description
|model
|Parent context variables <<textcomponentcontext-template-variables>>
|===
===== Confirmation
Used to ask a simple confirmation from a user and essentially is
yes/no question.
====
[source, java]
----
@ShellComponent
public class ComponentCommands extends AbstractShellComponent {
@ShellMethod(key = "component confirmation", value = "Confirmation input", group = "Components")
public String confirmationInput(boolean no) {
ConfirmationInput component = new ConfirmationInput(getTerminal(), "Enter value", !no);
component.setResourceLoader(getResourceLoader());
component.setTemplateExecutor(getTemplateExecutor());
ConfirmationInputContext context = component.run(ConfirmationInputContext.empty());
return "Got value " + context.getResultValue();
}
}
----
====
image::images/component-confirmation-1.svg[text input]
Context object is `ConfirmationInputContext`.
[[confirmationinputcontext-template-variables]]
.ConfirmationInputContext Template Variables
|===
|Key |Description
|defaultValue
|Default value, either true or false.
|model
|Parent context variables <<textcomponentcontext-template-variables>>
|===
===== Single Select
Used to ask an item from a list and is essentially similar to simple
dropbox implementation.
====
[source, java]
----
@ShellComponent
public class ComponentCommands extends AbstractShellComponent {
@ShellMethod(key = "component single", value = "Single selector", group = "Components")
public String singleSelector() {
List<SelectorItem<String>> items = new ArrayList<>();
items.add(SelectorItem.of("key1", "value1"));
items.add(SelectorItem.of("key2", "value2"));
SingleItemSelector<String, SelectorItem<String>> component = new SingleItemSelector<>(getTerminal(),
items, "testSimple", null);
component.setResourceLoader(getResourceLoader());
component.setTemplateExecutor(getTemplateExecutor());
SingleItemSelectorContext<String, SelectorItem<String>> context = component
.run(SingleItemSelectorContext.empty());
String result = context.getResultItem().flatMap(si -> Optional.ofNullable(si.getItem())).get();
return "Got value " + result;
}
}
----
====
image::images/component-single-select-1.svg[text input]
Context object is `SingleItemSelectorContext`.
[[singleitemselectorcontext-template-variables]]
.SingleItemSelectorContext Template Variables
|===
|Key |Description
|value
|Returned value when component exists.
|rows
|Visible items where rows list contains maps of name and selected items.
|model
|Parent context variables <<selectorcomponentcontext-template-variables>>
|===
===== Multi Select
Used to ask an items from a list.
====
[source, java]
----
@ShellComponent
public class ComponentCommands extends AbstractShellComponent {
@ShellMethod(key = "component multi", value = "Multi selector", group = "Components")
public String multiSelector() {
List<SelectorItem<String>> items = new ArrayList<>();
items.add(SelectorItem.of("key1", "value1"));
items.add(SelectorItem.of("key2", "value2", false));
items.add(SelectorItem.of("key3", "value3"));
MultiItemSelector<String, SelectorItem<String>> component = new MultiItemSelector<>(getTerminal(),
items, "testSimple", null);
component.setResourceLoader(getResourceLoader());
component.setTemplateExecutor(getTemplateExecutor());
MultiItemSelectorContext<String, SelectorItem<String>> context = component
.run(MultiItemSelectorContext.empty());
String result = context.getResultItems().stream()
.map(si -> si.getItem())
.collect(Collectors.joining(","));
return "Got value " + result;
}
}
----
====
image::images/component-multi-select-1.svg[text input]
Context object is `MultiItemSelectorContext`.
[[multiitemselectorcontext-template-variables]]
.MultiItemSelectorContext Template Variables
|===
|Key |Description
|values
|Returned values when component exists.
|rows
|Visible items where rows list contains maps of name, selected, onrow and enabled items.
|model
|Parent context variables <<selectorcomponentcontext-template-variables>>
|===
=== Customizing the Shell