23
spring-shell-docs/readme.txt
Normal file
23
spring-shell-docs/readme.txt
Normal 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
|
||||
@@ -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"]
|
||||
@@ -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"]
|
||||
@@ -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"]
|
||||
@@ -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"]
|
||||
@@ -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 |
@@ -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
|
||||
|
||||
|
||||
Reference in New Issue
Block a user