@@ -965,3 +965,192 @@ describe("Validation inside a form", () => {
965965 . should ( "have.been.calledOnce" ) ;
966966 } ) ;
967967} ) ;
968+
969+ describe ( "TextArea Composition" , ( ) => {
970+ it ( "should handle Korean composition correctly" , ( ) => {
971+ cy . mount (
972+ < TextArea
973+ id = "textarea-composition-korean"
974+ placeholder = "Type in Korean ..."
975+ />
976+ ) ;
977+
978+ cy . get ( "[ui5-textarea]" )
979+ . as ( "textarea" )
980+ . realClick ( ) ;
981+
982+ cy . get ( "@textarea" )
983+ . shadow ( )
984+ . find ( "textarea" )
985+ . as ( "nativeTextarea" )
986+ . focus ( ) ;
987+
988+ cy . get ( "@nativeTextarea" ) . trigger ( "compositionstart" , { data : "" } ) ;
989+
990+ cy . get ( "@textarea" ) . should ( "have.prop" , "_isComposing" , true ) ;
991+
992+ cy . get ( "@nativeTextarea" ) . trigger ( "compositionupdate" , { data : "사랑" } ) ;
993+
994+ cy . get ( "@textarea" ) . should ( "have.prop" , "_isComposing" , true ) ;
995+
996+ cy . get ( "@nativeTextarea" ) . trigger ( "compositionend" , { data : "사랑" } ) ;
997+
998+ cy . get ( "@nativeTextarea" )
999+ . invoke ( "val" , "사랑" )
1000+ . trigger ( "input" , { inputType : "insertCompositionText" } ) ;
1001+
1002+ cy . get ( "@textarea" ) . should ( "have.prop" , "_isComposing" , false ) ;
1003+
1004+ cy . get ( "@textarea" ) . should ( "have.attr" , "value" , "사랑" ) ;
1005+ } ) ;
1006+
1007+ it ( "should handle Japanese composition correctly" , ( ) => {
1008+ cy . mount (
1009+ < TextArea
1010+ id = "textarea-composition-japanese"
1011+ placeholder = "Type in Japanese ..."
1012+ />
1013+ ) ;
1014+
1015+ cy . get ( "[ui5-textarea]" )
1016+ . as ( "textarea" )
1017+ . realClick ( ) ;
1018+
1019+ cy . get ( "@textarea" )
1020+ . shadow ( )
1021+ . find ( "textarea" )
1022+ . as ( "nativeTextarea" )
1023+ . focus ( ) ;
1024+
1025+ cy . get ( "@nativeTextarea" ) . trigger ( "compositionstart" , { data : "" } ) ;
1026+
1027+ cy . get ( "@textarea" ) . should ( "have.prop" , "_isComposing" , true ) ;
1028+
1029+ cy . get ( "@nativeTextarea" ) . trigger ( "compositionupdate" , { data : "ありがとう" } ) ;
1030+
1031+ cy . get ( "@textarea" ) . should ( "have.prop" , "_isComposing" , true ) ;
1032+
1033+ cy . get ( "@nativeTextarea" ) . trigger ( "compositionend" , { data : "ありがとう" } ) ;
1034+
1035+ cy . get ( "@nativeTextarea" )
1036+ . invoke ( "val" , "ありがとう" )
1037+ . trigger ( "input" , { inputType : "insertCompositionText" } ) ;
1038+
1039+ cy . get ( "@textarea" ) . should ( "have.prop" , "_isComposing" , false ) ;
1040+
1041+ cy . get ( "@textarea" ) . should ( "have.attr" , "value" , "ありがとう" ) ;
1042+ } ) ;
1043+
1044+ it ( "should handle Chinese composition correctly" , ( ) => {
1045+ cy . mount (
1046+ < TextArea
1047+ id = "textarea-composition-chinese"
1048+ placeholder = "Type in Chinese ..."
1049+ />
1050+ ) ;
1051+
1052+ cy . get ( "[ui5-textarea]" )
1053+ . as ( "textarea" )
1054+ . realClick ( ) ;
1055+
1056+ cy . get ( "@textarea" )
1057+ . shadow ( )
1058+ . find ( "textarea" )
1059+ . as ( "nativeTextarea" )
1060+ . focus ( ) ;
1061+
1062+ cy . get ( "@nativeTextarea" ) . trigger ( "compositionstart" , { data : "" } ) ;
1063+
1064+ cy . get ( "@textarea" ) . should ( "have.prop" , "_isComposing" , true ) ;
1065+
1066+ cy . get ( "@nativeTextarea" ) . trigger ( "compositionupdate" , { data : "谢谢" } ) ;
1067+
1068+ cy . get ( "@textarea" ) . should ( "have.prop" , "_isComposing" , true ) ;
1069+
1070+ cy . get ( "@nativeTextarea" ) . trigger ( "compositionend" , { data : "谢谢" } ) ;
1071+
1072+ cy . get ( "@nativeTextarea" )
1073+ . invoke ( "val" , "谢谢" )
1074+ . trigger ( "input" , { inputType : "insertCompositionText" } ) ;
1075+
1076+ cy . get ( "@textarea" ) . should ( "have.prop" , "_isComposing" , false ) ;
1077+
1078+ cy . get ( "@textarea" ) . should ( "have.attr" , "value" , "谢谢" ) ;
1079+ } ) ;
1080+
1081+ it ( "should not revert value on Escape during composition" , ( ) => {
1082+ cy . mount (
1083+ < TextArea
1084+ id = "textarea-composition-escape"
1085+ value = "initial"
1086+ />
1087+ ) ;
1088+
1089+ cy . get ( "[ui5-textarea]" )
1090+ . as ( "textarea" )
1091+ . realClick ( ) ;
1092+
1093+ cy . get ( "@textarea" )
1094+ . shadow ( )
1095+ . find ( "textarea" )
1096+ . as ( "nativeTextarea" )
1097+ . focus ( ) ;
1098+
1099+ cy . get ( "@nativeTextarea" ) . trigger ( "compositionstart" , { data : "" } ) ;
1100+
1101+ cy . get ( "@textarea" ) . should ( "have.prop" , "_isComposing" , true ) ;
1102+
1103+ cy . get ( "@nativeTextarea" ) . trigger ( "compositionupdate" , { data : "테스트" } ) ;
1104+
1105+ cy . get ( "@nativeTextarea" )
1106+ . invoke ( "val" , "initial테스트" )
1107+ . trigger ( "input" , { inputType : "insertCompositionText" } ) ;
1108+
1109+ cy . get ( "@nativeTextarea" ) . trigger ( "keydown" , { key : "Escape" , keyCode : 27 } ) ;
1110+
1111+ cy . get ( "@textarea" ) . should ( "have.attr" , "value" , "initial테스트" ) ;
1112+
1113+ cy . get ( "@nativeTextarea" ) . trigger ( "compositionend" , { data : "테스트" } ) ;
1114+
1115+ cy . get ( "@textarea" ) . should ( "have.prop" , "_isComposing" , false ) ;
1116+
1117+ cy . get ( "@textarea" ) . should ( "have.attr" , "value" , "initial테스트" ) ;
1118+ } ) ;
1119+
1120+ it ( "should revert value on Escape after composition ends" , ( ) => {
1121+ cy . mount (
1122+ < TextArea
1123+ id = "textarea-composition-escape-after"
1124+ value = "initial"
1125+ />
1126+ ) ;
1127+
1128+ cy . get ( "[ui5-textarea]" )
1129+ . as ( "textarea" )
1130+ . realClick ( ) ;
1131+
1132+ cy . get ( "@textarea" )
1133+ . shadow ( )
1134+ . find ( "textarea" )
1135+ . as ( "nativeTextarea" )
1136+ . focus ( ) ;
1137+
1138+ cy . get ( "@nativeTextarea" ) . trigger ( "compositionstart" , { data : "" } ) ;
1139+
1140+ cy . get ( "@nativeTextarea" ) . trigger ( "compositionupdate" , { data : "완료" } ) ;
1141+
1142+ cy . get ( "@nativeTextarea" )
1143+ . invoke ( "val" , "initial완료" )
1144+ . trigger ( "input" , { inputType : "insertCompositionText" } ) ;
1145+
1146+ cy . get ( "@nativeTextarea" ) . trigger ( "compositionend" , { data : "완료" } ) ;
1147+
1148+ cy . get ( "@textarea" ) . should ( "have.prop" , "_isComposing" , false ) ;
1149+
1150+ cy . get ( "@textarea" ) . should ( "have.attr" , "value" , "initial완료" ) ;
1151+
1152+ cy . get ( "@nativeTextarea" ) . realPress ( "Escape" ) ;
1153+
1154+ cy . get ( "@textarea" ) . should ( "have.attr" , "value" , "initial" ) ;
1155+ } ) ;
1156+ } ) ;
0 commit comments