@shell-shock/plugin-prompts 0.2.1 → 0.2.3

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.
@@ -207,7 +207,7 @@ function BasePromptDeclarations() {
207
207
  }),
208
208
  createComponent(Spacing, {}),
209
209
  createComponent(InterfaceMember, {
210
- name: "maskSubmitted",
210
+ name: "maskCompleted",
211
211
  optional: true,
212
212
  type: "(input: string) => string",
213
213
  doc: "A function that masks the value submitted by the user so that it can then be used in the console output or elsewhere without exposing sensitive information. If not provided, the prompt will use the same mask function for both input and submitted value masking."
@@ -254,6 +254,20 @@ function BasePromptDeclarations() {
254
254
  type: "TValue"
255
255
  }),
256
256
  createIntrinsic("hbr", {}),
257
+ createComponent(ClassField, {
258
+ name: "isKeyPressed",
259
+ isPrivateMember: true,
260
+ type: "boolean",
261
+ children: code`false; `
262
+ }),
263
+ createIntrinsic("hbr", {}),
264
+ createComponent(ClassField, {
265
+ name: "isDirty",
266
+ isPrivateMember: true,
267
+ type: "boolean",
268
+ children: code`false; `
269
+ }),
270
+ createIntrinsic("hbr", {}),
257
271
  createComponent(ClassField, {
258
272
  name: "isClosed",
259
273
  isPrivateMember: true,
@@ -381,7 +395,7 @@ function BasePromptDeclarations() {
381
395
  }),
382
396
  createIntrinsic("hbr", {}),
383
397
  createComponent(ClassField, {
384
- name: "maskSubmitted",
398
+ name: "maskCompleted",
385
399
  "protected": true,
386
400
  type: "(input: string) => string"
387
401
  }),
@@ -432,14 +446,14 @@ function BasePromptDeclarations() {
432
446
  this.formatter = config.format.bind(this);
433
447
  }
434
448
 
435
- if (config.maskSubmitted) {
436
- this.maskSubmitted = config.maskSubmitted;
449
+ if (config.maskCompleted) {
450
+ this.maskCompleted = config.maskCompleted;
437
451
  }
438
452
  if (config.mask) {
439
453
  this.mask = config.mask;
440
454
  }
441
- if (!this.maskSubmitted) {
442
- this.maskSubmitted = this.mask;
455
+ if (!this.maskCompleted) {
456
+ this.maskCompleted = this.mask;
443
457
  }
444
458
 
445
459
  if (config.timeout !== undefined && !Number.isNaN(config.timeout)) {
@@ -462,7 +476,11 @@ function BasePromptDeclarations() {
462
476
  this.input.setRawMode(true);
463
477
  }
464
478
 
465
- this.input.on("keypress", this.onKeypress.bind(this));
479
+ this.input.on("keypress", this.keypress.bind(this));
480
+ }
481
+
482
+ [Symbol.dispose]() {
483
+ this.close();
466
484
  } `,
467
485
  createComponent(Spacing, {}),
468
486
  createComponent(ClassPropertyGet, {
@@ -498,24 +516,42 @@ function BasePromptDeclarations() {
498
516
  "protected": true,
499
517
  name: "isPlaceholder",
500
518
  type: "boolean",
501
- children: code`return this.config.initialValue !== undefined && this.displayValue === this.formatter(this.initialValue); `
519
+ children: code`return (this.displayValue === this.formatter(this.parser(this.initialValue)) && !this.#isDirty) || !this.#isKeyPressed; `
502
520
  }),
503
521
  createComponent(Spacing, {}),
504
522
  createComponent(ClassPropertyGet, {
505
523
  "protected": true,
506
524
  name: "status",
507
525
  type: "string",
508
- children: code`return this.isCompleted ? "" : \` \\n \${
526
+ children: code`return this.isSubmitted ? "" : \` \\n \${
509
527
  colors.italic(
510
528
  this.isError
511
529
  ? colors.text.prompt.description.error(splitText(this.errorMessage, "3/4").join("\\n"))
512
- : this.description
513
- ? colors.text.prompt.description.active(splitText(this.description, "3/4").join("\\n"))
514
- : ""
530
+ : this.isCancelled
531
+ ? colors.text.prompt.description.cancelled(splitText("Input was cancelled by user", "3/4").join("\\n"))
532
+ : this.description
533
+ ? colors.text.prompt.description.active(splitText(this.description, "3/4").join("\\n"))
534
+ : ""
515
535
  )
516
536
  }\`; `
517
537
  }),
518
538
  createComponent(Spacing, {}),
539
+ createComponent(ClassPropertyGet, {
540
+ doc: "A property to check if the cursor is at the start",
541
+ name: "isCursorAtStart",
542
+ "protected": true,
543
+ type: "boolean",
544
+ children: code`return this.cursor === 0 || (this.isPlaceholder && this.cursor === 1); `
545
+ }),
546
+ createComponent(Spacing, {}),
547
+ createComponent(ClassPropertyGet, {
548
+ doc: "A property to check if the cursor is at the end",
549
+ name: "isCursorAtEnd",
550
+ "protected": true,
551
+ type: "boolean",
552
+ children: code`return this.cursor === this.displayValue.length || (this.isPlaceholder && this.cursor === this.displayValue.length - 1); `
553
+ }),
554
+ createComponent(Spacing, {}),
519
555
  createComponent(ClassMethod, {
520
556
  doc: "A method to change the prompt value, which also updates the display value and fires a state update event. This method can be called by subclasses whenever the prompt value needs to be updated based on user input or other interactions.",
521
557
  name: "changeValue",
@@ -524,7 +560,9 @@ function BasePromptDeclarations() {
524
560
  name: "value",
525
561
  type: "TValue"
526
562
  }],
527
- children: code`let updatedValue = value;
563
+ children: code`const previousValue = this.value;
564
+
565
+ let updatedValue = value;
528
566
  if (value === undefined || value === "") {
529
567
  updatedValue = this.initialValue;
530
568
  } else {
@@ -533,6 +571,12 @@ function BasePromptDeclarations() {
533
571
 
534
572
  this.displayValue = this.mask(this.formatter(updatedValue));
535
573
  this.#value = updatedValue;
574
+
575
+ if (!this.#isDirty && this.#value !== this.initialValue) {
576
+ this.#isDirty = true;
577
+ }
578
+
579
+ this.onChange(previousValue);
536
580
  setTimeout(() => {
537
581
  Promise.resolve(this.validate(updatedValue)).then(() => this.sync());
538
582
  }, 0);
@@ -552,7 +596,7 @@ function BasePromptDeclarations() {
552
596
  isCancelled: this.isCancelled,
553
597
  isCompleted: this.isCompleted
554
598
  });
555
- this.invokeRender(); `
599
+ this.render(); `
556
600
  }),
557
601
  createComponent(Spacing, {}),
558
602
  createComponent(ClassMethod, {
@@ -563,26 +607,35 @@ function BasePromptDeclarations() {
563
607
  }),
564
608
  createComponent(Spacing, {}),
565
609
  createComponent(ClassMethod, {
566
- doc: "A method to handle keypress events and determine the corresponding action",
567
- name: "onKeypress",
610
+ doc: "A method to render the prompt",
611
+ name: "onRender",
612
+ "protected": true,
613
+ returnType: "string",
614
+ children: code`return this.isPlaceholder
615
+ ? colors.text.prompt.input.disabled(this.displayValue)
616
+ : this.isError
617
+ ? colors.text.prompt.input.error(this.displayValue)
618
+ : this.isSubmitted
619
+ ? colors.text.prompt.input.submitted(this.maskCompleted(this.displayValue))
620
+ : this.isCancelled
621
+ ? colors.text.prompt.input.cancelled(this.maskCompleted(this.displayValue))
622
+ : colors.bold(colors.text.prompt.input.active(this.displayValue)); `
623
+ }),
624
+ createComponent(Spacing, {}),
625
+ createComponent(ClassMethod, {
626
+ doc: "A method to handle changes in the prompt value",
627
+ name: "onChange",
568
628
  "protected": true,
569
629
  parameters: [{
570
- name: "char",
571
- type: "string"
572
- }, {
573
- name: "key",
574
- type: "readline.Key"
630
+ name: "previousValue",
631
+ type: "TValue"
575
632
  }],
576
- children: code`if (this.#isClosed) {
577
- return;
578
- }
579
-
580
- return this.keypress(char, key); `
633
+ children: code` // can be implemented by subclasses to handle value changes if needed, this method is called whenever the prompt value changes and receives the previous value as an argument for reference`
581
634
  }),
582
635
  createComponent(Spacing, {}),
583
636
  createComponent(ClassMethod, {
584
- doc: "A method to handle keypress events and determine the corresponding action",
585
- name: "keypress",
637
+ doc: "A method to handle key press events and determine the corresponding action",
638
+ name: "onKeyPress",
586
639
  "protected": true,
587
640
  parameters: [{
588
641
  name: "char",
@@ -592,11 +645,11 @@ function BasePromptDeclarations() {
592
645
  type: "readline.Key"
593
646
  }],
594
647
  children: code`const action = this.getAction(key);
595
- if (!action) {
596
- this.bell();
597
- } else if (typeof (this as any)[action] === "function") {
598
- (this as any)[action](key);
599
- } `
648
+ if (!action) {
649
+ this.bell();
650
+ } else if (typeof (this as any)[action] === "function") {
651
+ (this as any)[action](key);
652
+ } `
600
653
  }),
601
654
  createComponent(Spacing, {}),
602
655
  createComponent(ClassMethod, {
@@ -604,8 +657,12 @@ function BasePromptDeclarations() {
604
657
  name: "close",
605
658
  async: true,
606
659
  "protected": true,
607
- children: code`this.output.write(cursor.show);
608
- this.input.removeListener("keypress", this.onKeypress);
660
+ children: code`if (this.#isClosed) {
661
+ return;
662
+ }
663
+
664
+ this.output.write(cursor.show);
665
+ this.input.removeListener("keypress", this.keypress);
609
666
 
610
667
  if (this.input.isTTY) {
611
668
  this.input.setRawMode(false);
@@ -636,7 +693,7 @@ function BasePromptDeclarations() {
636
693
  }),
637
694
  createComponent(Spacing, {}),
638
695
  createComponent(ClassMethod, {
639
- doc: "A method to route keypress events to specific prompt actions based on the key pressed. This method maps various key combinations and keys to corresponding actions that can be handled by the prompt, such as submitting, cancelling, navigating, etc.",
696
+ doc: "A method to route key press events to specific prompt actions based on the key pressed. This method maps various key combinations and keys to corresponding actions that can be handled by the prompt, such as submitting, cancelling, navigating, etc.",
640
697
  name: "getAction",
641
698
  "protected": true,
642
699
  parameters: [{
@@ -675,6 +732,70 @@ function BasePromptDeclarations() {
675
732
  if (key.name === "left") action = "left";
676
733
 
677
734
  return action || false; `
735
+ }),
736
+ createComponent(Spacing, {}),
737
+ createComponent(ClassMethod, {
738
+ doc: "A method to move the cursor to the left or right by a \\`count\\` of positions",
739
+ name: "moveCursor",
740
+ parameters: [{
741
+ name: "count",
742
+ type: "number"
743
+ }],
744
+ "protected": true,
745
+ children: code`
746
+ this.cursor += count;
747
+ this.cursorOffset += count; `
748
+ }),
749
+ createComponent(Spacing, {}),
750
+ createComponent(ClassMethod, {
751
+ doc: "A method to delete the character backward of the cursor",
752
+ name: "delete",
753
+ "protected": true,
754
+ children: code`if (this.isCursorAtStart) {
755
+ return this.bell();
756
+ }
757
+
758
+ if (this.displayValue === "") {
759
+ return this.bell();
760
+ }
761
+
762
+ this.changeValue(\`\${
763
+ this.displayValue.slice(0, this.cursor - 1)
764
+ }\${
765
+ this.displayValue.slice(this.cursor)
766
+ }\`);
767
+
768
+ if (this.isCursorAtStart) {
769
+ this.cursorOffset = 0;
770
+ } else {
771
+ this.cursorOffset++;
772
+ this.moveCursor(-1);
773
+ }
774
+
775
+ this.sync(); `
776
+ }),
777
+ createComponent(Spacing, {}),
778
+ createComponent(ClassMethod, {
779
+ doc: "A method to delete the character forward of the cursor",
780
+ name: "deleteForward",
781
+ "protected": true,
782
+ children: code`if (this.cursor >= this.displayValue.length) {
783
+ return this.bell();
784
+ }
785
+
786
+ this.changeValue(\`\${
787
+ this.displayValue.slice(0, this.cursor)
788
+ }\${
789
+ this.displayValue.slice(this.cursor + 1)
790
+ }\`);
791
+
792
+ if (this.isCursorAtEnd) {
793
+ this.cursorOffset = 0;
794
+ } else {
795
+ this.cursorOffset++;
796
+ }
797
+
798
+ this.sync(); `
678
799
  }),
679
800
  createComponent(Spacing, {}),
680
801
  createComponent(ClassMethod, {
@@ -728,8 +849,8 @@ function BasePromptDeclarations() {
728
849
  createComponent(Spacing, {}),
729
850
  createComponent(ClassMethod, {
730
851
  doc: "A method to render the prompt",
731
- name: "invokeRender",
732
- "protected": true,
852
+ name: "render",
853
+ "private": true,
733
854
  get children() {
734
855
  return code`if (this.#isClosed) {
735
856
  return;
@@ -764,7 +885,7 @@ function BasePromptDeclarations() {
764
885
  : (process.platform === "win32" ? "»" : "›")
765
886
  )
766
887
  } \`;
767
- this.consoleOutput += this.render();
888
+ this.consoleOutput += this.onRender();
768
889
 
769
890
  if (this.isInitial) {
770
891
  this.isInitial = false;
@@ -776,19 +897,25 @@ function BasePromptDeclarations() {
776
897
  }),
777
898
  createComponent(Spacing, {}),
778
899
  createComponent(ClassMethod, {
779
- doc: "A method to render the prompt",
780
- name: "render",
781
- "protected": true,
782
- returnType: "string",
783
- children: code`return this.isPlaceholder
784
- ? colors.text.prompt.input.disabled(this.displayValue)
785
- : this.isError
786
- ? colors.text.prompt.input.error(this.displayValue)
787
- : this.isSubmitted
788
- ? colors.text.prompt.input.submitted(this.maskSubmitted(this.displayValue))
789
- : this.isCancelled
790
- ? colors.text.prompt.input.cancelled(this.displayValue)
791
- : colors.bold(colors.text.prompt.input.active(this.displayValue)); `
900
+ doc: "A method to handle key press events and determine the corresponding action",
901
+ name: "keypress",
902
+ "private": true,
903
+ parameters: [{
904
+ name: "char",
905
+ type: "string"
906
+ }, {
907
+ name: "key",
908
+ type: "readline.Key"
909
+ }],
910
+ children: code`if (this.#isClosed) {
911
+ return;
912
+ }
913
+
914
+ if (!this.#isKeyPressed) {
915
+ this.#isKeyPressed = true;
916
+ }
917
+
918
+ return this.onKeyPress(char, key); `
792
919
  })
793
920
  ];
794
921
  }
@@ -918,8 +1045,8 @@ function TextPromptDeclarations() {
918
1045
  } `,
919
1046
  createComponent(Spacing, {}),
920
1047
  createComponent(ClassMethod, {
921
- doc: "A method to handle keypress events and determine the corresponding action",
922
- name: "keypress",
1048
+ doc: "A method to handle onKeyPress events and determine the corresponding action",
1049
+ name: "onKeyPress",
923
1050
  override: true,
924
1051
  "protected": true,
925
1052
  parameters: [{
@@ -938,31 +1065,38 @@ function TextPromptDeclarations() {
938
1065
  return this.bell();
939
1066
  }
940
1067
 
941
- const value = \`\${this.value.slice(0, this.cursor)}\${char}\${this.value.slice(this.cursor)}\`;
942
- this.#isInvalid = false;
943
- this.cursor = this.isPlaceholder ? 0 : this.value.slice(0, this.cursor).length + 1;
1068
+ const value = \`\${
1069
+ this.value.slice(0, this.cursor)
1070
+ }\${
1071
+ char
1072
+ }\${
1073
+ this.value.slice(this.cursor)
1074
+ }\`;
944
1075
 
945
1076
  this.changeValue(value);
946
1077
  this.sync(); `
947
1078
  }),
948
1079
  createComponent(Spacing, {}),
949
1080
  createComponent(ClassMethod, {
950
- doc: "A method to reset the prompt input",
951
- name: "reset",
1081
+ doc: "A method to handle changes in the prompt value",
1082
+ name: "onChange",
952
1083
  override: true,
953
1084
  "protected": true,
1085
+ parameters: [{
1086
+ name: "previousValue",
1087
+ type: "TValue"
1088
+ }],
954
1089
  children: code`this.#isInvalid = false;
955
- this.cursor = Number(!!this.initialValue);
956
- super.reset(); `
1090
+ this.cursor = this.displayValue.slice(0, this.cursor).length + 1; `
957
1091
  }),
958
1092
  createComponent(Spacing, {}),
959
1093
  createComponent(ClassMethod, {
960
- doc: "A method to cancel the prompt input",
961
- name: "cancel",
1094
+ doc: "A method to reset the prompt input",
1095
+ name: "reset",
962
1096
  override: true,
963
1097
  "protected": true,
964
- children: code`this.#isInvalid = false;
965
- super.cancel(); `
1098
+ children: code`this.cursor = Number(!!this.initialValue);
1099
+ super.reset(); `
966
1100
  }),
967
1101
  createComponent(Spacing, {}),
968
1102
  createComponent(ClassMethod, {
@@ -979,73 +1113,8 @@ function TextPromptDeclarations() {
979
1113
  doc: "A method to move the cursor to the end of the input",
980
1114
  name: "next",
981
1115
  "protected": true,
982
- children: code`if (!this.isPlaceholder) {
983
- return this.bell();
984
- }
985
-
986
- this.changeValue(this.initialValue);
1116
+ children: code`this.changeValue(this.initialValue);
987
1117
  this.cursor = this.displayValue.length;
988
- this.sync(); `
989
- }),
990
- createComponent(Spacing, {}),
991
- createComponent(ClassMethod, {
992
- doc: "A method to move the cursor to the left or right by a \\`count\\` of positions",
993
- name: "moveCursor",
994
- parameters: [{
995
- name: "count",
996
- type: "number"
997
- }],
998
- "protected": true,
999
- children: code`if (this.isPlaceholder) {
1000
- return;
1001
- }
1002
-
1003
- this.cursor = this.cursor + count;
1004
- this.cursorOffset += count; `
1005
- }),
1006
- createComponent(Spacing, {}),
1007
- createComponent(ClassMethod, {
1008
- doc: "A method to delete the character backward of the cursor",
1009
- name: "delete",
1010
- "protected": true,
1011
- children: code`if (this.isCursorAtStart()) {
1012
- return this.bell();
1013
- }
1014
-
1015
- this.changeValue(\`\${this.value.slice(0, this.cursor - 1)}\${this.value.slice(this.cursor)}\`);
1016
- this.#isInvalid = false;
1017
-
1018
- if (this.isCursorAtStart()) {
1019
- this.cursorOffset = 0
1020
- } else {
1021
- this.cursorOffset++;
1022
- this.moveCursor(-1);
1023
- }
1024
-
1025
- this.sync(); `
1026
- }),
1027
- createComponent(Spacing, {}),
1028
- createComponent(ClassMethod, {
1029
- doc: "A method to delete the character forward of the cursor",
1030
- name: "deleteForward",
1031
- "protected": true,
1032
- children: code`if (this.cursor >= this.displayValue.length || this.isPlaceholder) {
1033
- return this.bell();
1034
- }
1035
-
1036
- this.changeValue(\`\${
1037
- this.value.slice(0, this.cursor)
1038
- }\${
1039
- this.value.slice(this.cursor + 1)
1040
- }\`);
1041
- this.#isInvalid = false;
1042
-
1043
- if (this.isCursorAtEnd()) {
1044
- this.cursorOffset = 0;
1045
- } else {
1046
- this.cursorOffset++;
1047
- }
1048
-
1049
1118
  this.sync(); `
1050
1119
  }),
1051
1120
  createComponent(Spacing, {}),
@@ -1069,7 +1138,7 @@ function TextPromptDeclarations() {
1069
1138
  doc: "A method to move the cursor to the left",
1070
1139
  name: "left",
1071
1140
  "protected": true,
1072
- children: code`if (this.cursor <= 0 || this.isPlaceholder) {
1141
+ children: code`if (this.cursor <= 0) {
1073
1142
  return this.bell();
1074
1143
  }
1075
1144
 
@@ -1081,7 +1150,7 @@ function TextPromptDeclarations() {
1081
1150
  doc: "A method to move the cursor to the right",
1082
1151
  name: "right",
1083
1152
  "protected": true,
1084
- children: code`if (this.cursor >= this.displayValue.length || this.isPlaceholder) {
1153
+ children: code`if (this.cursor >= this.displayValue.length) {
1085
1154
  return this.bell();
1086
1155
  }
1087
1156
 
@@ -1089,23 +1158,9 @@ function TextPromptDeclarations() {
1089
1158
  this.sync(); `
1090
1159
  }),
1091
1160
  createComponent(Spacing, {}),
1092
- createComponent(ClassMethod, {
1093
- doc: "A method to check if the cursor is at the start",
1094
- name: "isCursorAtStart",
1095
- "protected": true,
1096
- children: code`return this.cursor === 0 || (this.isPlaceholder && this.cursor === 1); `
1097
- }),
1098
- createComponent(Spacing, {}),
1099
- createComponent(ClassMethod, {
1100
- doc: "A method to check if the cursor is at the end",
1101
- name: "isCursorAtEnd",
1102
- "protected": true,
1103
- children: code`return this.cursor === this.displayValue.length || (this.isPlaceholder && this.cursor === this.displayValue.length + 1); `
1104
- }),
1105
- createComponent(Spacing, {}),
1106
1161
  createComponent(ClassMethod, {
1107
1162
  doc: "A method to render the prompt",
1108
- name: "render",
1163
+ name: "onRender",
1109
1164
  override: true,
1110
1165
  "protected": true,
1111
1166
  returnType: "string",
@@ -1174,7 +1229,7 @@ run(); ` }),
1174
1229
 
1175
1230
  prompt.on("state", state => config.onState?.(state));
1176
1231
  prompt.on("submit", value => response(value));
1177
- prompt.on("cancel", event => reject(CANCEL_SYMBOL));
1232
+ prompt.on("cancel", event => response(CANCEL_SYMBOL));
1178
1233
  });`
1179
1234
  })
1180
1235
  ];
@@ -1402,7 +1457,7 @@ function SelectPromptDeclarations() {
1402
1457
  }),
1403
1458
  createComponent(Spacing, {}),
1404
1459
  createComponent(ClassMethod, {
1405
- doc: "A method to route keypress events to specific prompt actions based on the key pressed. This method maps various key combinations and keys to corresponding actions that can be handled by the prompt, such as submitting, cancelling, navigating, etc.",
1460
+ doc: "A method to route key press events to specific prompt actions based on the key pressed. This method maps various key combinations and keys to corresponding actions that can be handled by the prompt, such as submitting, cancelling, navigating, etc.",
1406
1461
  name: "getAction",
1407
1462
  override: true,
1408
1463
  "protected": true,
@@ -1457,6 +1512,7 @@ function SelectPromptDeclarations() {
1457
1512
  name: "count",
1458
1513
  type: "number"
1459
1514
  }],
1515
+ override: true,
1460
1516
  "protected": true,
1461
1517
  children: code`this.cursor = count;
1462
1518
 
@@ -1516,7 +1572,7 @@ function SelectPromptDeclarations() {
1516
1572
  createComponent(Spacing, {}),
1517
1573
  createComponent(ClassMethod, {
1518
1574
  doc: "A method to render the prompt",
1519
- name: "render",
1575
+ name: "onRender",
1520
1576
  override: true,
1521
1577
  "protected": true,
1522
1578
  children: code`const spacing = Math.max(...this.options.map(option => option.label?.length || 0)) + 2;
@@ -1568,7 +1624,7 @@ function SelectPromptDeclarations() {
1568
1624
  }
1569
1625
  } else {
1570
1626
  this.displayValue = this.selectedOption?.label || String(this.value);
1571
- output += super.render();
1627
+ output += super.onRender();
1572
1628
  }
1573
1629
 
1574
1630
  return output; `
@@ -1638,7 +1694,7 @@ run(); ` }),
1638
1694
 
1639
1695
  prompt.on("state", state => config.onState?.(state));
1640
1696
  prompt.on("submit", value => response(value));
1641
- prompt.on("cancel", event => reject(CANCEL_SYMBOL));
1697
+ prompt.on("cancel", event => response(CANCEL_SYMBOL));
1642
1698
  });`
1643
1699
  })
1644
1700
  ];
@@ -1755,20 +1811,6 @@ function NumericPromptDeclarations() {
1755
1811
  type: "number",
1756
1812
  children: code`Number.POSITIVE_INFINITY; `
1757
1813
  }),
1758
- createIntrinsic("hbr", {}),
1759
- createComponent(ClassField, {
1760
- name: "currentInput",
1761
- "protected": true,
1762
- type: "string",
1763
- children: code`""; `
1764
- }),
1765
- createIntrinsic("hbr", {}),
1766
- createComponent(ClassField, {
1767
- name: "inputTimestamp",
1768
- "protected": true,
1769
- type: "number",
1770
- children: code`0; `
1771
- }),
1772
1814
  createComponent(Spacing, {}),
1773
1815
  code`constructor(config: NumberPromptConfig) {
1774
1816
  super(config);
@@ -1805,23 +1847,13 @@ function NumericPromptDeclarations() {
1805
1847
  this.validator = validator.bind(this);
1806
1848
  }
1807
1849
 
1850
+ this.changeValue(this.initialValue);
1808
1851
  this.sync();
1809
- this.last();
1810
1852
  } `,
1811
1853
  createComponent(Spacing, {}),
1812
1854
  createComponent(ClassMethod, {
1813
- doc: "A method to reset the prompt input",
1814
- name: "reset",
1815
- override: true,
1816
- "protected": true,
1817
- children: code`super.reset();
1818
- this.currentInput = "";
1819
- `
1820
- }),
1821
- createComponent(Spacing, {}),
1822
- createComponent(ClassMethod, {
1823
- doc: "A method to handle keypress events and determine the corresponding action",
1824
- name: "keypress",
1855
+ doc: "A method to handle key press events and determine the corresponding action",
1856
+ name: "onKeyPress",
1825
1857
  override: true,
1826
1858
  "protected": true,
1827
1859
  parameters: [{
@@ -1836,25 +1868,55 @@ function NumericPromptDeclarations() {
1836
1868
  return (this as any)[action]();
1837
1869
  }
1838
1870
 
1839
- if (char !== "-" && !(char === "." && this.isFloat) && !/[0-9]/.test(char)) {
1871
+ if ((char !== "-" || (char === "-" && this.cursor !== 0)) && !(char === "." && this.isFloat) && !/[0-9]/.test(char)) {
1840
1872
  return this.bell();
1841
1873
  }
1842
1874
 
1843
- this.displayValue += char;
1844
- if ((char === "-" || char === ".") && this.displayValue.length === 1) {
1845
- return this.sync();
1846
- }
1875
+ const displayValue = \`\${
1876
+ this.displayValue.slice(0, this.cursor)
1877
+ }\${
1878
+ char
1879
+ }\${
1880
+ this.displayValue.slice(this.cursor)
1881
+ }\`;
1847
1882
 
1848
- let value = Math.min(this.parser(this.displayValue), this.max);
1849
- if (value > this.max) {
1850
- value = this.max;
1851
- }
1852
- if (value < this.min) {
1853
- value = this.min;
1883
+ let value = this.parser(displayValue);
1884
+ if (!Number.isNaN(value)) {
1885
+
1886
+ value = Math.min(value, this.max);
1887
+ if (value > this.max) {
1888
+ value = this.max;
1889
+ }
1890
+ if (value < this.min) {
1891
+ value = this.min;
1892
+ }
1854
1893
  }
1855
1894
 
1856
1895
  this.changeValue(value);
1857
1896
  this.sync(); `
1897
+ }),
1898
+ createComponent(Spacing, {}),
1899
+ createComponent(ClassMethod, {
1900
+ doc: "A method to handle changes in the prompt value",
1901
+ name: "onChange",
1902
+ override: true,
1903
+ "protected": true,
1904
+ parameters: [{
1905
+ name: "previousValue",
1906
+ type: "TValue"
1907
+ }],
1908
+ children: code`this.#isInvalid = false;
1909
+ this.cursor = this.displayValue.slice(0, this.cursor).length + 1; `
1910
+ }),
1911
+ createComponent(Spacing, {}),
1912
+ createComponent(ClassMethod, {
1913
+ doc: "A method to validate the prompt input",
1914
+ name: "validate",
1915
+ override: true,
1916
+ async: true,
1917
+ "protected": true,
1918
+ children: code`await super.validate(this.value);
1919
+ this.#isInvalid = this.isError; `
1858
1920
  }),
1859
1921
  createComponent(Spacing, {}),
1860
1922
  createComponent(ClassMethod, {
@@ -1899,7 +1961,7 @@ function NumericPromptDeclarations() {
1899
1961
  doc: "A method to move the cursor to the left",
1900
1962
  name: "left",
1901
1963
  "protected": true,
1902
- children: code`if (this.cursor <= 0 || this.isPlaceholder) {
1964
+ children: code`if (this.cursor <= 0) {
1903
1965
  return this.bell();
1904
1966
  }
1905
1967
 
@@ -1911,76 +1973,11 @@ function NumericPromptDeclarations() {
1911
1973
  doc: "A method to move the cursor to the right",
1912
1974
  name: "right",
1913
1975
  "protected": true,
1914
- children: code`if (this.cursor >= this.displayValue.length || this.isPlaceholder) {
1976
+ children: code`if (this.cursor >= this.displayValue.length) {
1915
1977
  return this.bell();
1916
1978
  }
1917
1979
 
1918
1980
  this.moveCursor(1);
1919
- this.sync(); `
1920
- }),
1921
- createComponent(Spacing, {}),
1922
- createComponent(ClassMethod, {
1923
- doc: "A method to move the cursor to the left or right by a \\`count\\` of positions",
1924
- name: "moveCursor",
1925
- parameters: [{
1926
- name: "count",
1927
- type: "number"
1928
- }],
1929
- "protected": true,
1930
- children: code`if (this.isPlaceholder) {
1931
- return;
1932
- }
1933
-
1934
- this.cursor = this.cursor + count;
1935
- this.cursorOffset += count; `
1936
- }),
1937
- createComponent(Spacing, {}),
1938
- createComponent(ClassMethod, {
1939
- doc: "A method to delete the character backward of the cursor",
1940
- name: "delete",
1941
- "protected": true,
1942
- children: code`if (this.isCursorAtStart()) {
1943
- return this.bell();
1944
- }
1945
-
1946
- if (this.displayValue === "") {
1947
- return this.bell();
1948
- }
1949
-
1950
- this.changeValue(\`\${this.displayValue.slice(0, this.cursor - 1)}\${this.displayValue.slice(this.cursor)}\`);
1951
- this.#isInvalid = false;
1952
-
1953
- if (this.isCursorAtStart()) {
1954
- this.cursorOffset = 0
1955
- } else {
1956
- this.cursorOffset++;
1957
- this.moveCursor(-1);
1958
- }
1959
-
1960
- this.sync(); `
1961
- }),
1962
- createComponent(Spacing, {}),
1963
- createComponent(ClassMethod, {
1964
- doc: "A method to delete the character forward of the cursor",
1965
- name: "deleteForward",
1966
- "protected": true,
1967
- children: code`if (this.cursor >= this.displayValue.length || this.isPlaceholder) {
1968
- return this.bell();
1969
- }
1970
-
1971
- this.changeValue(\`\${
1972
- this.displayValue.slice(0, this.cursor)
1973
- }\${
1974
- this.displayValue.slice(this.cursor + 1)
1975
- }\`);
1976
- this.#isInvalid = false;
1977
-
1978
- if (this.isCursorAtEnd()) {
1979
- this.cursorOffset = 0;
1980
- } else {
1981
- this.cursorOffset++;
1982
- }
1983
-
1984
1981
  this.sync(); `
1985
1982
  }),
1986
1983
  createComponent(Spacing, {}),
@@ -2001,17 +1998,20 @@ function NumericPromptDeclarations() {
2001
1998
  }),
2002
1999
  createComponent(Spacing, {}),
2003
2000
  createComponent(ClassMethod, {
2004
- doc: "A method to check if the cursor is at the start",
2005
- name: "isCursorAtStart",
2006
- "protected": true,
2007
- children: code`return this.cursor === 0 || (this.isPlaceholder && this.cursor === 1); `
2008
- }),
2009
- createComponent(Spacing, {}),
2010
- createComponent(ClassMethod, {
2011
- doc: "A method to check if the cursor is at the end",
2012
- name: "isCursorAtEnd",
2001
+ doc: "A method to render the prompt",
2002
+ name: "onRender",
2003
+ override: true,
2013
2004
  "protected": true,
2014
- children: code`return this.cursor === this.displayValue.length || (this.isPlaceholder && this.cursor === this.displayValue.length + 1); `
2005
+ returnType: "string",
2006
+ children: code`return this.isPlaceholder
2007
+ ? colors.text.prompt.input.disabled(this.displayValue)
2008
+ : this.#isInvalid
2009
+ ? colors.text.prompt.input.error(this.displayValue)
2010
+ : this.isSubmitted
2011
+ ? colors.text.prompt.input.submitted(this.displayValue)
2012
+ : this.isCancelled
2013
+ ? colors.text.prompt.input.cancelled(this.displayValue)
2014
+ : colors.bold(colors.text.prompt.input.active(this.displayValue)); `
2015
2015
  })
2016
2016
  ];
2017
2017
  }
@@ -2067,7 +2067,7 @@ run(); ` }),
2067
2067
 
2068
2068
  prompt.on("state", state => config.onState?.(state));
2069
2069
  prompt.on("submit", value => response(value));
2070
- prompt.on("cancel", event => reject(CANCEL_SYMBOL));
2070
+ prompt.on("cancel", event => response(CANCEL_SYMBOL));
2071
2071
  });`
2072
2072
  })
2073
2073
  ];
@@ -2181,8 +2181,8 @@ function TogglePromptDeclarations() {
2181
2181
  }),
2182
2182
  createComponent(Spacing, {}),
2183
2183
  createComponent(ClassMethod, {
2184
- doc: "A method to handle keypress events and determine the corresponding action",
2185
- name: "keypress",
2184
+ doc: "A method to handle key press events and determine the corresponding action",
2185
+ name: "onKeyPress",
2186
2186
  override: true,
2187
2187
  "protected": true,
2188
2188
  parameters: [{
@@ -2255,7 +2255,7 @@ function TogglePromptDeclarations() {
2255
2255
  createComponent(Spacing, {}),
2256
2256
  createComponent(ClassMethod, {
2257
2257
  doc: "A method to render the prompt",
2258
- name: "render",
2258
+ name: "onRender",
2259
2259
  override: true,
2260
2260
  "protected": true,
2261
2261
  returnType: "string",
@@ -2321,7 +2321,7 @@ run(); ` }),
2321
2321
 
2322
2322
  prompt.on("state", state => config.onState?.(state));
2323
2323
  prompt.on("submit", value => response(value));
2324
- prompt.on("cancel", event => reject(CANCEL_SYMBOL));
2324
+ prompt.on("cancel", event => response(CANCEL_SYMBOL));
2325
2325
  });`
2326
2326
  })
2327
2327
  ];
@@ -2484,8 +2484,8 @@ function ConfirmPromptDeclarations() {
2484
2484
  } `,
2485
2485
  createComponent(Spacing, {}),
2486
2486
  createComponent(ClassMethod, {
2487
- doc: "A method to handle keypress events and determine the corresponding action",
2488
- name: "keypress",
2487
+ doc: "A method to handle key press events and determine the corresponding action",
2488
+ name: "onKeyPress",
2489
2489
  override: true,
2490
2490
  "protected": true,
2491
2491
  parameters: [{
@@ -2515,7 +2515,7 @@ function ConfirmPromptDeclarations() {
2515
2515
  createComponent(Spacing, {}),
2516
2516
  createComponent(ClassMethod, {
2517
2517
  doc: "A method to render the prompt",
2518
- name: "render",
2518
+ name: "onRender",
2519
2519
  override: true,
2520
2520
  "protected": true,
2521
2521
  returnType: "string",
@@ -2577,7 +2577,7 @@ run(); ` }),
2577
2577
 
2578
2578
  prompt.on("state", state => config.onState?.(state));
2579
2579
  prompt.on("submit", value => response(value));
2580
- prompt.on("cancel", event => reject(CANCEL_SYMBOL));
2580
+ prompt.on("cancel", event => response(CANCEL_SYMBOL));
2581
2581
  }); `
2582
2582
  })
2583
2583
  ];
@@ -2603,7 +2603,7 @@ function PasswordPromptDeclaration() {
2603
2603
  createComponent(TypeDeclaration, {
2604
2604
  name: "PasswordConfig",
2605
2605
  "export": true,
2606
- children: code`Omit<TextConfig, "mask" | "maskSubmitted">; `
2606
+ children: code`Omit<TextConfig, "mask" | "maskCompleted">; `
2607
2607
  }),
2608
2608
  createComponent(Spacing, {}),
2609
2609
  createComponent(TSDoc, {
@@ -2647,7 +2647,7 @@ run(); ` }),
2647
2647
  children: code`return text({
2648
2648
  ...config,
2649
2649
  mask: passwordMask,
2650
- maskSubmitted: () => "*******"
2650
+ maskCompleted: () => "*******"
2651
2651
  });`
2652
2652
  })
2653
2653
  ];