@capillarytech/creatives-library 9.0.26 → 9.0.29-alpha.1

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.
Files changed (149) hide show
  1. package/constants/unified.js +29 -0
  2. package/global-styles.js +1 -1
  3. package/package.json +1 -1
  4. package/services/tests/api.test.js +35 -20
  5. package/utils/commonUtils.js +22 -1
  6. package/utils/rcsPayloadUtils.js +102 -0
  7. package/utils/templateVarUtils.js +198 -0
  8. package/utils/tests/rcsPayloadUtils.test.js +295 -0
  9. package/utils/tests/templateVarUtils.test.js +204 -0
  10. package/v2Components/CapActionButton/constants.js +21 -1
  11. package/v2Components/CapActionButton/index.js +260 -144
  12. package/v2Components/CapActionButton/index.scss +245 -14
  13. package/v2Components/CapActionButton/messages.js +32 -3
  14. package/v2Components/CapActionButton/tests/index.test.js +74 -19
  15. package/v2Components/CapImageUpload/index.js +2 -2
  16. package/v2Components/CapTagList/index.js +9 -0
  17. package/v2Components/CommonTestAndPreview/CustomValuesEditor.js +70 -48
  18. package/v2Components/CommonTestAndPreview/DeliverySettings/DeliverySettings.scss +8 -2
  19. package/v2Components/CommonTestAndPreview/DeliverySettings/ModifyDeliverySettings.js +214 -21
  20. package/v2Components/CommonTestAndPreview/DeliverySettings/constants.js +16 -0
  21. package/v2Components/CommonTestAndPreview/DeliverySettings/index.js +83 -9
  22. package/v2Components/CommonTestAndPreview/DeliverySettings/messages.js +30 -0
  23. package/v2Components/CommonTestAndPreview/DeliverySettings/utils/parseSenderDetailsResponse.js +58 -11
  24. package/v2Components/CommonTestAndPreview/SendTestMessage.js +10 -5
  25. package/v2Components/CommonTestAndPreview/UnifiedPreview/RcsPreviewContent.js +186 -22
  26. package/v2Components/CommonTestAndPreview/UnifiedPreview/_unifiedPreview.scss +381 -80
  27. package/v2Components/CommonTestAndPreview/UnifiedPreview/index.js +155 -8
  28. package/v2Components/CommonTestAndPreview/_commonTestAndPreview.scss +11 -0
  29. package/v2Components/CommonTestAndPreview/constants.js +35 -2
  30. package/v2Components/CommonTestAndPreview/index.js +770 -231
  31. package/v2Components/CommonTestAndPreview/messages.js +45 -3
  32. package/v2Components/CommonTestAndPreview/previewApiUtils.js +59 -0
  33. package/v2Components/CommonTestAndPreview/sagas.js +25 -6
  34. package/v2Components/CommonTestAndPreview/tests/CommonTestAndPreview.addTestCustomer.test.js +1 -0
  35. package/v2Components/CommonTestAndPreview/tests/CustomValuesEditor.test.js +412 -257
  36. package/v2Components/CommonTestAndPreview/tests/DeliverySettings/ModifyDeliverySettings.test.js +337 -63
  37. package/v2Components/CommonTestAndPreview/tests/DeliverySettings/index.test.js +118 -5
  38. package/v2Components/CommonTestAndPreview/tests/DeliverySettings/utils/parseSenderDetailsResponse.test.js +341 -0
  39. package/v2Components/CommonTestAndPreview/tests/PreviewSection.test.js +8 -1
  40. package/v2Components/CommonTestAndPreview/tests/SendTestMessage.test.js +108 -15
  41. package/v2Components/CommonTestAndPreview/tests/UnifiedPreview/RcsPreviewContent.test.js +281 -283
  42. package/v2Components/CommonTestAndPreview/tests/UnifiedPreview/index.test.js +199 -1
  43. package/v2Components/CommonTestAndPreview/tests/index.test.js +133 -4
  44. package/v2Components/CommonTestAndPreview/tests/previewApiUtils.test.js +67 -0
  45. package/v2Components/CommonTestAndPreview/tests/sagas.test.js +31 -24
  46. package/v2Components/CommonTestAndPreview/tests/utils.test.js +151 -0
  47. package/v2Components/CommonTestAndPreview/utils.js +84 -0
  48. package/v2Components/SmsFallback/SmsFallbackLocalSelector.js +91 -0
  49. package/v2Components/SmsFallback/constants.js +94 -0
  50. package/v2Components/SmsFallback/index.js +958 -0
  51. package/v2Components/SmsFallback/index.scss +266 -0
  52. package/v2Components/SmsFallback/messages.js +78 -0
  53. package/v2Components/SmsFallback/smsFallbackUtils.js +120 -0
  54. package/v2Components/SmsFallback/tests/SmsFallbackLocalSelector.test.js +50 -0
  55. package/v2Components/SmsFallback/tests/rcsSmsFallback.acceptance.test.js +147 -0
  56. package/v2Components/SmsFallback/tests/smsFallbackHandlers.test.js +304 -0
  57. package/v2Components/SmsFallback/tests/smsFallbackUi.test.js +208 -0
  58. package/v2Components/SmsFallback/tests/smsFallbackUtils.test.js +309 -0
  59. package/v2Components/SmsFallback/tests/useLocalTemplateList.test.js +471 -0
  60. package/v2Components/SmsFallback/useLocalTemplateList.js +92 -0
  61. package/v2Components/TemplatePreview/_templatePreview.scss +45 -25
  62. package/v2Components/TemplatePreview/constants.js +2 -0
  63. package/v2Components/TemplatePreview/index.js +147 -32
  64. package/v2Components/TemplatePreview/tests/index.test.js +142 -0
  65. package/v2Components/TestAndPreviewSlidebox/CustomValuesEditor.js +6 -6
  66. package/v2Components/TestAndPreviewSlidebox/index.js +13 -1
  67. package/v2Components/TestAndPreviewSlidebox/sagas.js +11 -4
  68. package/v2Components/TestAndPreviewSlidebox/tests/saga.test.js +3 -1
  69. package/v2Components/VarSegmentMessageEditor/constants.js +2 -0
  70. package/v2Components/VarSegmentMessageEditor/index.js +125 -0
  71. package/v2Components/VarSegmentMessageEditor/index.scss +46 -0
  72. package/v2Containers/CommunicationFlow/Tests/CommunicationFlow.test.js +4 -1
  73. package/v2Containers/CommunicationFlow/steps/DeliverySettingsStep/Tests/DeliverySettingsSection.test.js +4 -0
  74. package/v2Containers/CommunicationFlow/steps/DeliverySettingsStep/Tests/SenderDetails.test.js +20 -20
  75. package/v2Containers/CreativesContainer/CreativesSlideBoxWrapper.js +27 -0
  76. package/v2Containers/CreativesContainer/SlideBoxContent.js +37 -4
  77. package/v2Containers/CreativesContainer/SlideBoxFooter.js +14 -5
  78. package/v2Containers/CreativesContainer/SlideBoxHeader.js +36 -5
  79. package/v2Containers/CreativesContainer/constants.js +11 -0
  80. package/v2Containers/CreativesContainer/embeddedSlideboxUtils.js +77 -0
  81. package/v2Containers/CreativesContainer/index.js +328 -106
  82. package/v2Containers/CreativesContainer/index.scss +102 -1
  83. package/v2Containers/CreativesContainer/tests/CreativesSlideBoxWrapper.test.js +58 -0
  84. package/v2Containers/CreativesContainer/tests/SlideBoxContent.localTemplates.test.js +90 -0
  85. package/v2Containers/CreativesContainer/tests/SlideBoxContent.smsDltPreview.test.js +73 -0
  86. package/v2Containers/CreativesContainer/tests/SlideBoxContent.test.js +37 -0
  87. package/v2Containers/CreativesContainer/tests/SlideBoxFooter.test.js +103 -34
  88. package/v2Containers/CreativesContainer/tests/SlideBoxHeader.test.js +193 -15
  89. package/v2Containers/CreativesContainer/tests/__snapshots__/SlideBoxContent.test.js.snap +88 -0
  90. package/v2Containers/CreativesContainer/tests/__snapshots__/SlideBoxHeader.test.js.snap +549 -57
  91. package/v2Containers/CreativesContainer/tests/__snapshots__/index.test.js.snap +20 -15
  92. package/v2Containers/CreativesContainer/tests/embeddedSlideboxUtils.test.js +258 -0
  93. package/v2Containers/CreativesContainer/tests/index.test.js +71 -9
  94. package/v2Containers/CreativesContainer/tests/useLocalTemplatesProp.test.js +125 -0
  95. package/v2Containers/Email/index.js +3 -54
  96. package/v2Containers/EmailWrapper/hooks/useEmailWrapper.js +4 -9
  97. package/v2Containers/MobilePush/Create/test/saga.test.js +2 -2
  98. package/v2Containers/Rcs/carouselUtils.js +224 -0
  99. package/v2Containers/Rcs/components/CarouselCard.js +317 -0
  100. package/v2Containers/Rcs/components/CarouselCardButtons.js +113 -0
  101. package/v2Containers/Rcs/components/CarouselCardMedia.js +136 -0
  102. package/v2Containers/Rcs/components/CarouselCharacterCount.js +31 -0
  103. package/v2Containers/Rcs/components/CarouselDimensionSelection.js +80 -0
  104. package/v2Containers/Rcs/constants.js +132 -16
  105. package/v2Containers/Rcs/index.js +1808 -949
  106. package/v2Containers/Rcs/index.scss +443 -8
  107. package/v2Containers/Rcs/messages.js +45 -22
  108. package/v2Containers/Rcs/rcsLibraryHydrationUtils.js +484 -0
  109. package/v2Containers/Rcs/tests/CarouselCard.test.js +464 -0
  110. package/v2Containers/Rcs/tests/CarouselCardButtons.test.js +211 -0
  111. package/v2Containers/Rcs/tests/CarouselCardMedia.test.js +160 -0
  112. package/v2Containers/Rcs/tests/CarouselCharacterCount.test.js +50 -0
  113. package/v2Containers/Rcs/tests/CarouselDimensionSelection.test.js +119 -0
  114. package/v2Containers/Rcs/tests/__snapshots__/index.test.js.snap +74176 -39409
  115. package/v2Containers/Rcs/tests/__snapshots__/utils.test.js.snap +10 -74
  116. package/v2Containers/Rcs/tests/carouselUtils.test.js +916 -0
  117. package/v2Containers/Rcs/tests/index.test.js +219 -40
  118. package/v2Containers/Rcs/tests/mockData.js +38 -0
  119. package/v2Containers/Rcs/tests/rcsLibraryHydrationUtils.test.js +873 -0
  120. package/v2Containers/Rcs/tests/utils.test.js +682 -30
  121. package/v2Containers/Rcs/utils.js +514 -12
  122. package/v2Containers/Sms/Create/index.js +115 -48
  123. package/v2Containers/Sms/smsFormDataHelpers.js +67 -0
  124. package/v2Containers/Sms/tests/smsFormDataHelpers.test.js +253 -0
  125. package/v2Containers/SmsTrai/Create/index.js +9 -4
  126. package/v2Containers/SmsTrai/Edit/constants.js +2 -0
  127. package/v2Containers/SmsTrai/Edit/index.js +678 -169
  128. package/v2Containers/SmsTrai/Edit/index.scss +126 -0
  129. package/v2Containers/SmsTrai/Edit/messages.js +14 -4
  130. package/v2Containers/SmsTrai/Edit/tests/__snapshots__/index.test.js.snap +5615 -3014
  131. package/v2Containers/SmsWrapper/index.js +37 -8
  132. package/v2Containers/TagList/index.js +5 -0
  133. package/v2Containers/Templates/TemplatesActionBar.js +101 -0
  134. package/v2Containers/Templates/_templates.scss +196 -12
  135. package/v2Containers/Templates/actions.js +11 -0
  136. package/v2Containers/Templates/constants.js +2 -0
  137. package/v2Containers/Templates/index.js +131 -59
  138. package/v2Containers/Templates/sagas.js +57 -13
  139. package/v2Containers/Templates/tests/TemplatesActionBar.test.js +129 -0
  140. package/v2Containers/Templates/tests/__snapshots__/index.test.js.snap +1060 -1015
  141. package/v2Containers/Templates/tests/sagas.test.js +199 -16
  142. package/v2Containers/Templates/tests/smsTemplatesListApi.test.js +180 -0
  143. package/v2Containers/Templates/utils/smsTemplatesListApi.js +79 -0
  144. package/v2Containers/TemplatesV2/TemplatesV2.style.js +72 -1
  145. package/v2Containers/TemplatesV2/index.js +88 -25
  146. package/v2Containers/TemplatesV2/tests/TemplatesV2.localTemplates.test.js +131 -0
  147. package/v2Containers/WeChat/MapTemplates/test/saga.test.js +9 -9
  148. package/v2Containers/Whatsapp/index.js +3 -20
  149. package/v2Containers/Whatsapp/tests/__snapshots__/index.test.js.snap +578 -34
@@ -5,18 +5,58 @@
5
5
  position: fixed;
6
6
  bottom: 0;
7
7
  width: 100%;
8
- margin-left: -32px;
8
+ margin-left: -2rem;
9
9
  padding: $CAP_SPACE_32 $CAP_SPACE_24;
10
- margin-top: 40px;
10
+ margin-top: 2.5rem;
11
11
  z-index: 1;
12
12
  .ant-btn {
13
13
  margin-right: $CAP_SPACE_16;
14
14
  }
15
+
16
+ .rcs-test-preview-btn {
17
+ margin-left: $CAP_SPACE_08;
18
+ }
19
+ }
20
+
21
+ // Shared between the standalone form (.cap-rcs-creatives) and the slidebox header.
22
+ .rcs-creative-name-readonly {
23
+ margin-bottom: $CAP_SPACE_24;
24
+ }
25
+
26
+ .rcs-creative-name-value {
27
+ margin-top: $CAP_SPACE_08;
28
+ font-weight: 400;
15
29
  }
16
30
 
17
31
  .cap-rcs-creatives {
32
+
18
33
  .rcs-scroll-div {
19
- margin-bottom: 150px;
34
+ margin-bottom: 9.375rem;
35
+ }
36
+
37
+ &.rcs-edit-mode {
38
+ .rcs-scroll-div {
39
+ margin-bottom: 15.625rem;
40
+ }
41
+
42
+ .rcs-edit-template-message-input {
43
+ background-color: $CAP_G10;
44
+ padding: $CAP_SPACE_12 $CAP_SPACE_16;
45
+ }
46
+
47
+ .rcs-edit-template-message-split {
48
+ margin-bottom: $CAP_SPACE_08;
49
+ overflow: hidden;
50
+ text-overflow: ellipsis;
51
+ color: $FONT_COLOR_03;
52
+ font-weight: 500;
53
+ }
54
+ }
55
+
56
+ /* Keep message box text lighter across RCS flows */
57
+ .rcs-edit-template-message-split {
58
+ color: $FONT_COLOR_03;
59
+ font-weight: 500;
20
60
  }
21
61
  .rcs-preview-container {
22
62
  .cap-row-v2 {
@@ -24,18 +64,53 @@
24
64
  }
25
65
  }
26
66
  .rcs-optional-label {
27
- margin-left: 8px;
67
+ margin-left: $CAP_SPACE_08;
28
68
  color: $FONT_COLOR_03;
29
69
  font-weight: normal;
30
70
  }
31
71
  .rcs_text_area_wrapper {
32
72
  position: relative;
33
73
  }
74
+ .rcs-edit-template-message-input .ant-input,
75
+ .rcs-edit-template-message-input textarea.ant-input {
76
+ border-color: $CAP_G07;
77
+ box-shadow: none;
78
+ min-height: 2.5rem;
79
+ padding-top: $CAP_SPACE_08;
80
+ padding-bottom: $CAP_SPACE_08;
81
+ overflow: hidden;
82
+ }
83
+ .rcs-edit-template-message-input .ant-input:focus,
84
+ .rcs-edit-template-message-input .ant-input:active,
85
+ .rcs-edit-template-message-input textarea.ant-input:focus,
86
+ .rcs-edit-template-message-input textarea.ant-input:active {
87
+ border-color: $CAP_G07;
88
+ box-shadow: none;
89
+ outline: none;
90
+ }
34
91
  .rcs-button{
35
92
  display: inline-grid;
36
93
  }
37
- .rcs-button-label{
38
- margin-bottom: 17px;
94
+ .rcs-form-field-caption {
95
+ margin-bottom: $CAP_SPACE_16;
96
+ }
97
+
98
+ .rcs-form-section-heading {
99
+ display: flex;
100
+ margin-top: $CAP_SPACE_20;
101
+ margin-bottom: $CAP_SPACE_08;
102
+ }
103
+
104
+ .rcs-image-upload--top-spacing {
105
+ padding-top: $CAP_SPACE_20;
106
+ }
107
+
108
+ .rcs-dimension-select--bottom-spacing {
109
+ margin-bottom: $CAP_SPACE_20;
110
+ }
111
+
112
+ .rcs-fallback-section-divider {
113
+ margin: $CAP_SPACE_28 0;
39
114
  }
40
115
  .disabled-button{
41
116
  opacity: 0.5;
@@ -62,9 +137,11 @@
62
137
  overflow: hidden;
63
138
  &.title{
64
139
  -webkit-line-clamp: 1;
140
+ line-clamp: 1;
65
141
  }
66
142
  &.desc{
67
143
  -webkit-line-clamp: 5;
144
+ line-clamp: 5;
68
145
  }
69
146
  &.rcs-button-text{
70
147
  padding-top: 13px;
@@ -73,18 +150,77 @@
73
150
  }
74
151
  .rcs-listing-image {
75
152
  margin-bottom: 8px;
76
- width: 220px;
77
- height: 103px;
153
+ width: 100%;
154
+ max-height: 7.357rem;
155
+ object-fit: cover;
156
+ display: block;
157
+ }
158
+
159
+ // Templates listing preview (RCS): carousel should show a "peek" of next card like WhatsApp listing.
160
+ &.rcs-template-listing-preview {
161
+ &.is-carousel {
162
+ .rcs-listing-carousel-scroll {
163
+ overflow-x: auto;
164
+ display: flex;
165
+ padding-top: $CAP_SPACE_06;
166
+ padding-right: $CAP_SPACE_06;
167
+ white-space: nowrap;
168
+ scrollbar-width: none;
169
+ &::-webkit-scrollbar {
170
+ display: none;
171
+ }
172
+ // Listing should show a peek (no horizontal scroll interaction needed)
173
+ overflow: hidden;
174
+ }
175
+
176
+ .rcs-listing-carousel-card {
177
+ padding: $CAP_SPACE_04 0 $CAP_SPACE_08;
178
+ border-radius: $CAP_SPACE_06;
179
+ background-color: $CAP_WHITE;
180
+ width: 80%;
181
+ flex-shrink: 0;
182
+ margin-right: $CAP_SPACE_04;
183
+ white-space: normal;
184
+ text-align: left;
185
+ }
186
+
187
+ .rcs-listing-carousel-img {
188
+ width: 100%;
189
+ height: 6.4375rem; // match rcs-listing-image height (103px)
190
+ object-fit: cover;
191
+ display: block;
192
+ margin-bottom: $CAP_SPACE_08;
193
+ }
194
+
195
+ .rcs-listing-carousel-title,
196
+ .rcs-listing-carousel-desc {
197
+ display: block;
198
+ padding: 0 $CAP_SPACE_12;
199
+ }
200
+ .rcs-listing-carousel-desc {
201
+ margin-top: $CAP_SPACE_04;
202
+ }
203
+ }
78
204
  }
79
205
  .fallback-sms-length {
80
206
  margin-top: 13px;
81
207
  float: right;
82
208
  }
209
+ .rcs-character-count {
210
+ color: $FONT_COLOR_03;
211
+ }
212
+
213
+ .rcs-carousel-character-count-row {
214
+ display: flex;
215
+ justify-content: flex-end;
216
+ margin-top: $CAP_SPACE_08;
217
+ }
83
218
  .rcs-fallback-len-error{
84
219
  margin-top: 8px;
85
220
  }
86
221
  .rcs-image-dimensions-label{
87
222
  margin-top: 1.25rem;
223
+ margin-bottom: $CAP_SPACE_08;
88
224
  }
89
225
  .rcs-template-title-input {
90
226
  .rcs-edit-disabled {
@@ -95,12 +231,14 @@
95
231
  }
96
232
  .rcs-template-title-label {
97
233
  margin-top: 1.25rem;
234
+ margin-bottom: $CAP_SPACE_08;
98
235
  }
99
236
  #rcs-template-message-label .ant-btn.cap-button-v2 {
100
237
  height: 32px;
101
238
  }
102
239
  #rcs-template-message-label {
103
240
  margin-top: 1.25rem;
241
+ margin-bottom: $CAP_SPACE_08;
104
242
  }
105
243
  .rcs-container-image {
106
244
  .image-container {
@@ -113,6 +251,297 @@
113
251
  #rcs-dimension-select{
114
252
  width: 100%;
115
253
  }
254
+
255
+ .rcs-carousel-section {
256
+ margin-top: $CAP_SPACE_12;
257
+ }
258
+
259
+ .rcs-carousel-dimension-section {
260
+ margin-top: 1.25rem;
261
+ }
262
+
263
+ // Edit mode: the readonly Template Type block right above (.rcs-creative-name-readonly)
264
+ // already has its own margin-bottom — stacking these two top-margins on top of that
265
+ // (flex prevents them from collapsing into it) left an oversized gap before Card height.
266
+ .rcs-carousel-section--readonly-above {
267
+ margin-top: 0;
268
+
269
+ .rcs-carousel-dimension-section {
270
+ margin-top: 0;
271
+ }
272
+ }
273
+
274
+ .rcs-carousel-selected-dimension {
275
+ display: block;
276
+ margin-top: 8px;
277
+ color: $FONT_COLOR_03;
278
+ }
279
+
280
+ .rcs-carousel-dimension-label {
281
+ display: inline-block;
282
+ margin-bottom: $CAP_SPACE_08;
283
+ }
284
+
285
+ #rcs-carousel-height-select,
286
+ #rcs-carousel-width-select {
287
+ width: 100%;
288
+ }
289
+
290
+ .rcs-carousel-tab {
291
+ margin-top: 0.75rem;
292
+
293
+ // Tab list (.ant-tabs-nav-wrap) defaults to flex:auto and stretches to fill the row,
294
+ // pushing tabBarExtraContent (the "+" add-card button) to the far right edge. Size it
295
+ // to its own content instead so "+" sits right next to the last tab (Figma reference).
296
+ .ant-tabs-nav-wrap {
297
+ flex: none;
298
+ }
299
+
300
+ // .ant-tabs-nav already centers its direct children (antd default), but antd
301
+ // also gives .ant-tabs-nav-wrap AND .ant-tabs-nav-operations (an always-present,
302
+ // just visually-hidden, third sibling for the overflow "more" dropdown)
303
+ // `align-self: stretch` — forcing them to the FULL bar height, while
304
+ // .ant-tabs-extra-content has no such override and centers at its own natural
305
+ // (shorter) height. So a divider centered inside the stretched tab list and a
306
+ // divider centered inside the un-stretched extra-content land at different Y
307
+ // positions even though each is individually "centered" — in its own box.
308
+ // Cancel the stretch so every direct child centers the same way.
309
+ .ant-tabs-nav {
310
+ align-items: center;
311
+
312
+ > .ant-tabs-nav-wrap,
313
+ > .ant-tabs-nav-operations {
314
+ align-self: auto;
315
+ }
316
+ }
317
+
318
+ // antd ALWAYS renders `.ant-tabs-nav-operations` as a flex sibling between the
319
+ // tab list and the right extra-content (it holds the overflow "more" dropdown).
320
+ // With no overflow it's only `visibility:hidden`, so it's invisible but STILL
321
+ // occupies a flex slot with real width — that phantom slot is the extra gap
322
+ // showing up before the "|" and "+". Collapse it to zero width when hidden so
323
+ // the divider sits the same distance from "2" as the 1|2 divider does from "1".
324
+ .ant-tabs-nav-operations.ant-tabs-nav-operations-hidden {
325
+ width: 0;
326
+ padding: 0;
327
+ margin: 0;
328
+ border: none;
329
+ }
330
+
331
+ // .ant-tabs-extra-content itself is only a flex ITEM (antd sets `flex: none`
332
+ // on it), not a flex CONTAINER — its own children (the CapDivider and the
333
+ // "+" button's tooltip-wrapper span) fall back to inline layout, where
334
+ // CapDivider's antd default `vertical-align: middle` aligns it to the
335
+ // surrounding line box rather than to the button, which is what was making
336
+ // the "|" and "+" drift out of alignment with each other. Make it an
337
+ // explicit flex row so both children center against each other directly.
338
+ .ant-tabs-extra-content {
339
+ display: flex;
340
+ align-items: center;
341
+ }
342
+
343
+ // Vertical divider between the tabs and "+": antd default (0.9em) reads too short.
344
+ // Also pin its own margin explicitly (antd's default didn't match the gap
345
+ // used for the divider between tab numbers below), which was making this
346
+ // divider float away from "2" instead of sitting the same distance from it
347
+ // as the 1|2 divider sits from "1".
348
+ // 12px each side = the same visual gap the 1|2 divider has (that one uses a
349
+ // 24px margin-left with the divider pseudo offset to its center, i.e. ~12px
350
+ // of clear space on each side). Keep these equal so all three gaps match.
351
+ .ant-tabs-extra-content .ant-divider-vertical {
352
+ height: $CAP_SPACE_24;
353
+ margin: 0 $CAP_SPACE_12;
354
+ }
355
+
356
+ // Same divider treatment between each numbered tab (1 | 2 | ...), not just
357
+ // before the "+" button (Figma reference). antd's own `.ant-tabs-tab` rule
358
+ // already applies `margin: 0 0 0 var(--ant-tabs-horizontal-item-gutter)`
359
+ // (~32px) to every tab — our earlier `margin-right` was ADDING to that
360
+ // instead of replacing it, stacking both gaps into one huge gutter before
361
+ // "2". Zero out antd's own margin first so this is the only gap in play.
362
+ .ant-tabs-tab {
363
+ margin: 0 !important;
364
+ }
365
+
366
+ // `:not(:last-of-type)` matched more than intended: antd renders
367
+ // `.ant-tabs-ink-bar` as another <div> sibling AFTER the last tab inside the
368
+ // same nav list, so that ink-bar div — not tab "2" — was `:last-of-type`,
369
+ // leaving tab "2" wrongly matched and given its own extra divider on top of
370
+ // the real one before "+". Target adjacency to a PRECEDING tab instead
371
+ // (`.ant-tabs-tab + .ant-tabs-tab`), which only ever matches actual tabs
372
+ // regardless of what non-tab siblings antd adds elsewhere in the list.
373
+ .ant-tabs-tab + .ant-tabs-tab {
374
+ position: relative;
375
+ margin-left: $CAP_SPACE_24 !important;
376
+
377
+ &::before {
378
+ content: '';
379
+ position: absolute;
380
+ top: 50%;
381
+ left: -$CAP_SPACE_12;
382
+ transform: translateY(-50%);
383
+ width: 1px;
384
+ height: $CAP_SPACE_24;
385
+ background-color: $CAP_G07;
386
+ }
387
+ }
388
+
389
+ // The "+" wrapper reuses .button-disabled-tooltip-wrapper from CapActionButton
390
+ // (display: inline-block; margin-top: 1.25rem) — that margin was meant for a
391
+ // different context and pushes the "+" button below the tab row/divider baseline
392
+ // here. Re-align it inline with the tabs and vertical divider.
393
+ .button-disabled-tooltip-wrapper {
394
+ display: inline-flex;
395
+ align-items: center;
396
+ margin-top: 0;
397
+ }
398
+ }
399
+
400
+ .rcs-carousel-card {
401
+ margin-top: 0.75rem;
402
+
403
+ // Match carousel card header: title left, icon-only delete right (Figma / product reference).
404
+ &.cap-card-v2.ant-card {
405
+ .ant-card-head {
406
+ min-height: 3rem;
407
+ padding: 0 $CAP_SPACE_16;
408
+ border-bottom: 1px solid $CAP_G12;
409
+ }
410
+
411
+ .ant-card-head-title {
412
+ padding: $CAP_SPACE_12 0;
413
+ font-weight: 600;
414
+ color: $CAP_G01;
415
+ }
416
+
417
+ .ant-card-extra {
418
+ padding: $CAP_SPACE_08 0;
419
+ }
420
+ }
421
+
422
+ .rcs-carousel-card-delete.ant-btn.cap-button-v2 {
423
+ display: inline-flex;
424
+ align-items: center;
425
+ justify-content: center;
426
+ min-width: auto;
427
+ width: 2rem;
428
+ height: 2rem;
429
+ padding: 0;
430
+ border: none;
431
+ box-shadow: none;
432
+ color: $CAP_G01;
433
+
434
+ &:not(:disabled):hover {
435
+ color: $FONT_COLOR_05;
436
+ background-color: rgba(0, 0, 0, 0.04);
437
+ }
438
+
439
+ &:disabled {
440
+ color: rgba(0, 0, 0, 0.25);
441
+ background: transparent;
442
+ }
443
+ }
444
+
445
+ .rcs-carousel-delete-tooltip-wrap.button-disabled-tooltip-wrapper {
446
+ display: inline-flex;
447
+ align-items: center;
448
+ cursor: not-allowed;
449
+ }
450
+ }
451
+
452
+ .rcs-carousel-card-row {
453
+ margin-bottom: $CAP_SPACE_12;
454
+
455
+ // Card title / Card body text headers sit directly above their input —
456
+ // CapHeader itself has no bottom margin, so without this the input hugged
457
+ // the header text with no gap.
458
+ .cap-header-v2 {
459
+ margin-bottom: $CAP_SPACE_08;
460
+ }
461
+ }
462
+
463
+ .rcs-carousel-media-selection {
464
+ margin-top: 0.75rem;
465
+ margin-bottom: 0.75rem;
466
+ align-items: center;
467
+ }
468
+
469
+ .rcs-carousel-media-selection-heading {
470
+ margin-bottom: $CAP_SPACE_08;
471
+ }
472
+
473
+ // Carousel upload previews: keep media preview compact (CapImageUpload uses height=400 by default)
474
+ .rcs-carousel-media-upload {
475
+ padding-top: $CAP_SPACE_20;
476
+
477
+ // Edit mode: the readonly Media type block right above (.rcs-creative-name-readonly)
478
+ // already has its own margin-bottom, plus .rcs-image-dimensions-label's own
479
+ // margin-top — stacking this padding-top on top of both left an oversized gap.
480
+ &.rcs-carousel-media-upload--readonly-above {
481
+ padding-top: 0;
482
+
483
+ // Only the first heading (Upload Video, or Image) sits right below the
484
+ // readonly block above — the video variant's second heading (Upload
485
+ // Thumbnail) still needs its own margin-top to separate it from the
486
+ // video upload widget above it.
487
+ > .rcs-image-dimensions-label:first-child {
488
+ margin-top: 0;
489
+ }
490
+ }
491
+ .image-container {
492
+ background-image: none;
493
+ border: 0;
494
+ width: 100%;
495
+ max-width: 35rem;
496
+ }
497
+
498
+ .image-container img {
499
+ width: 100%;
500
+ height: auto !important;
501
+ max-height: 15rem;
502
+ object-fit: contain;
503
+ display: block;
504
+ }
505
+ }
506
+
507
+ .rcs-carousel-card-divider {
508
+ margin: $CAP_SPACE_24 0;
509
+ }
510
+
511
+ .rcs-image-upload-with-top-padding {
512
+ padding-top: $CAP_SPACE_20;
513
+ }
514
+
515
+ .rcs-dlt-edit-icon {
516
+ margin-right: $CAP_SPACE_08;
517
+ }
518
+
519
+ .rcs-content-section-divider {
520
+ margin: $CAP_SPACE_28 0;
521
+ }
522
+
523
+ .rcs-edit-template-message-static-textarea {
524
+ background: $CAP_G21;
525
+ color: #888;
526
+
527
+ // Ensure styles apply to underlying textarea/input for CapInput TextArea.
528
+ textarea,
529
+ .ant-input {
530
+ background: $CAP_G21;
531
+ color: #888;
532
+ }
533
+ }
534
+
535
+ // The divider's own margin already provides the gap before "+" — this button's
536
+ // extra left padding was stacking on top of that margin, making the gap after
537
+ // the divider visibly bigger than the gap before it (between "2" and the
538
+ // divider). Drop the left padding so both sides of the divider match; keep a
539
+ // little on the right as breathing room since nothing follows "+".
540
+ .add-carousel-content-button {
541
+ padding: 0 $CAP_SPACE_08 0 0;
542
+ display: inline-flex;
543
+ align-items: center;
544
+ }
116
545
  }
117
546
  .rcs-fallback-preview > .cap-slide-box-v2-container.size-r{
118
547
  min-width: 430px;
@@ -120,6 +549,12 @@
120
549
  width: 430px;
121
550
  }
122
551
 
552
+ // SMS fallback slidebox / tag popover: see v2Components/SmsFallback/index.scss (loaded with SmsFallback)
553
+
554
+ .template-status-container {
555
+ margin-bottom: $CAP_SPACE_24;
556
+ }
557
+
123
558
  .rcs-button-cta{
124
559
  margin-top: 1.25rem;
125
560
  margin-bottom: 0.75rem;
@@ -6,6 +6,14 @@ export default defineMessages({
6
6
  id: `${prefix}.mediaLabel`,
7
7
  defaultMessage: 'Media',
8
8
  },
9
+ mediaTypeLabel: {
10
+ id: `${prefix}.mediaTypeLabel`,
11
+ defaultMessage: 'Media type',
12
+ },
13
+ carouselMediaVideoOption: {
14
+ id: `${prefix}.carouselMediaVideoOption`,
15
+ defaultMessage: 'Video',
16
+ },
9
17
  approvedStatusMsg: {
10
18
  id: `${prefix}.approvedStatusMsg`,
11
19
  defaultMessage: 'This template has been approved',
@@ -194,6 +202,18 @@ export default defineMessages({
194
202
  id: `${prefix}.disabledCarouselTooltip`,
195
203
  defaultMessage: 'Not yet enabled. Coming soon!',
196
204
  },
205
+ rcsCarouselMinCardDeleteTooltip: {
206
+ id: `${prefix}.rcsCarouselMinCardDeleteTooltip`,
207
+ defaultMessage: 'At least 1 card needs to be added in the carousel template',
208
+ },
209
+ rcsCarouselAddCardDisabledTooltip: {
210
+ id: `${prefix}.rcsCarouselAddCardDisabledTooltip`,
211
+ defaultMessage: 'Please set-up the first card before creating the next ones',
212
+ },
213
+ rcsCarouselMaxCardTooltip: {
214
+ id: `${prefix}.rcsCarouselMaxCardTooltip`,
215
+ defaultMessage: 'RCS carousel cannot contain more than {max} content cards.',
216
+ },
197
217
  templateNamePlaceholder: {
198
218
  id: `${prefix}.templateNamePlaceholder`,
199
219
  defaultMessage: 'Enter template name',
@@ -232,15 +252,15 @@ export default defineMessages({
232
252
  },
233
253
  text_message: {
234
254
  id: `${prefix}.text_message`,
235
- defaultMessage: 'text message',
255
+ defaultMessage: 'Text message',
236
256
  },
237
257
  richCard: {
238
258
  id: `${prefix}.richCard`,
239
- defaultMessage: 'rich card',
259
+ defaultMessage: 'Rich card',
240
260
  },
241
261
  carousel: {
242
262
  id: `${prefix}.carousel`,
243
- defaultMessage: 'carousel',
263
+ defaultMessage: 'Carousel',
244
264
  },
245
265
  rcsDoneBtnToolTip: {
246
266
  id: `${prefix}.rcsDoneBtnToolTip`,
@@ -262,6 +282,10 @@ export default defineMessages({
262
282
  id: `${prefix}.fallbackLabel`,
263
283
  defaultMessage: 'Fallback SMS message',
264
284
  },
285
+ smsFallbackOptional: {
286
+ id: `${prefix}.smsFallbackOptional`,
287
+ defaultMessage: 'Fallback SMS message (Optional)',
288
+ },
265
289
  fallbackDesc: {
266
290
  id: `${prefix}.fallbackDesc`,
267
291
  defaultMessage: 'We would suggest to add fallback SMS',
@@ -271,17 +295,18 @@ export default defineMessages({
271
295
  defaultMessage:
272
296
  'This is to deliver an RCS message as an SMS message to end users whose phones do not support RCS',
273
297
  },
274
- fallbackMsgLenError: {
275
- id: `${prefix}.fallbackMsgLenError`,
276
- defaultMessage: 'Only 1 SMS (160 characters) allowed for fallback sms',
277
- },
278
298
  fallbackTextAreaLabel: {
279
299
  id: `${prefix}.fallbackTextAreaLabel`,
280
300
  defaultMessage: 'SMS message',
281
301
  },
282
302
  fallbackMsgPlaceholder: {
283
303
  id: `${prefix}.fallbackMsgPlaceholder`,
284
- defaultMessage: 'Enter the text message content for fallback SMS',
304
+ defaultMessage: 'Add labels or text',
305
+ },
306
+ /** Shown only when a {{…}} slot has no value — not the saved text (that uses the input value). */
307
+ rcsVarSlotPlaceholder: {
308
+ id: `${prefix}.rcsVarSlotPlaceholder`,
309
+ defaultMessage: 'Add labels or text',
285
310
  },
286
311
  totalCharacters: {
287
312
  id: `${prefix}.totalCharacters`,
@@ -291,18 +316,6 @@ export default defineMessages({
291
316
  id: `${prefix}.addSmsCreative`,
292
317
  defaultMessage: 'Add SMS creative',
293
318
  },
294
- rcsDltTitle: {
295
- id: `${prefix}.rcsDltTitle`,
296
- defaultMessage: 'SMS creative templates',
297
- },
298
- rcsDltDesc: {
299
- id: `${prefix}.rcsDltDesc`,
300
- defaultMessage: 'Select any of the existing templates',
301
- },
302
- dltEditHeader: {
303
- id: `${prefix}.dltEditHeader`,
304
- defaultMessage: 'Edit SMS',
305
- },
306
319
  rcsCreateNotification: {
307
320
  id: `${prefix}.rcsCreateNotification`,
308
321
  defaultMessage: 'RCS template created successfully',
@@ -457,7 +470,8 @@ export default defineMessages({
457
470
  },
458
471
  unknownCharactersError: {
459
472
  id: `${prefix}.unknownCharactersError`,
460
- defaultMessage: 'Only alphanumeric characters and underscore are allowed in custom param. Spaces/other special characters are not allowed.',
473
+ defaultMessage:
474
+ 'Only letters, numbers, underscores, and dots are allowed in custom param (e.g. tag.FORMAT_1). Spaces and other special characters are not allowed.',
461
475
  },
462
476
  emptyVariableError: {
463
477
  id: `${prefix}.emptyVariableError`,
@@ -487,4 +501,13 @@ export default defineMessages({
487
501
  id: `${prefix}.rcsTestPreviewDisabledTooltip`,
488
502
  defaultMessage: 'Preview and test is only available after the template is approved.',
489
503
  },
490
- });
504
+ reUpload: {
505
+ id: `${prefix}.reUpload`,
506
+ defaultMessage: 'Reupload',
507
+ },
508
+ /** Carousel video card thumbnail size label (see RCS_CAROUSEL_VIDEO_THUMBNAIL_DIMENSIONS). */
509
+ rcsCarouselVideoThumbnailLabel: {
510
+ id: `${prefix}.rcsCarouselVideoThumbnailLabel`,
511
+ defaultMessage: 'Thumbnail ({width} × {height})',
512
+ },
513
+ });