@capillarytech/creatives-library 8.0.207 → 8.0.209

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 (77) hide show
  1. package/assets/Android.png +0 -0
  2. package/assets/iOS.png +0 -0
  3. package/package.json +16 -2
  4. package/v2Components/HtmlEditor/HTMLEditor.js +508 -0
  5. package/v2Components/HtmlEditor/__tests__/HTMLEditor.test.js +1809 -0
  6. package/v2Components/HtmlEditor/__tests__/index.lazy.test.js +532 -0
  7. package/v2Components/HtmlEditor/_htmlEditor.scss +304 -0
  8. package/v2Components/HtmlEditor/_index.lazy.scss +26 -0
  9. package/v2Components/HtmlEditor/components/CodeEditorPane/_codeEditorPane.scss +376 -0
  10. package/v2Components/HtmlEditor/components/CodeEditorPane/index.js +331 -0
  11. package/v2Components/HtmlEditor/components/DeviceToggle/__tests__/index.test.js +314 -0
  12. package/v2Components/HtmlEditor/components/DeviceToggle/_deviceToggle.scss +244 -0
  13. package/v2Components/HtmlEditor/components/DeviceToggle/index.js +111 -0
  14. package/v2Components/HtmlEditor/components/EditorToolbar/PreviewModeGroup.js +72 -0
  15. package/v2Components/HtmlEditor/components/EditorToolbar/__tests__/PreviewModeGroup.test.js +1594 -0
  16. package/v2Components/HtmlEditor/components/EditorToolbar/_editorToolbar.scss +113 -0
  17. package/v2Components/HtmlEditor/components/EditorToolbar/_previewModeGroup.scss +82 -0
  18. package/v2Components/HtmlEditor/components/EditorToolbar/index.js +115 -0
  19. package/v2Components/HtmlEditor/components/FullscreenModal/_fullscreenModal.scss +57 -0
  20. package/v2Components/HtmlEditor/components/InAppPreviewPane/ContentOverlay.js +90 -0
  21. package/v2Components/HtmlEditor/components/InAppPreviewPane/DeviceFrame.js +60 -0
  22. package/v2Components/HtmlEditor/components/InAppPreviewPane/LayoutSelector.js +58 -0
  23. package/v2Components/HtmlEditor/components/InAppPreviewPane/__tests__/ContentOverlay.test.js +389 -0
  24. package/v2Components/HtmlEditor/components/InAppPreviewPane/__tests__/DeviceFrame.test.js +424 -0
  25. package/v2Components/HtmlEditor/components/InAppPreviewPane/__tests__/LayoutSelector.test.js +248 -0
  26. package/v2Components/HtmlEditor/components/InAppPreviewPane/_inAppPreviewPane.scss +253 -0
  27. package/v2Components/HtmlEditor/components/InAppPreviewPane/constants.js +104 -0
  28. package/v2Components/HtmlEditor/components/InAppPreviewPane/index.js +179 -0
  29. package/v2Components/HtmlEditor/components/PreviewPane/_previewPane.scss +220 -0
  30. package/v2Components/HtmlEditor/components/PreviewPane/index.js +229 -0
  31. package/v2Components/HtmlEditor/components/SplitContainer/SplitContainer.js +276 -0
  32. package/v2Components/HtmlEditor/components/SplitContainer/__tests__/SplitContainer.test.js +295 -0
  33. package/v2Components/HtmlEditor/components/SplitContainer/_splitContainer.scss +257 -0
  34. package/v2Components/HtmlEditor/components/SplitContainer/index.js +7 -0
  35. package/v2Components/HtmlEditor/components/ValidationErrorDisplay/__tests__/index.test.js +152 -0
  36. package/v2Components/HtmlEditor/components/ValidationErrorDisplay/_validationErrorDisplay.scss +31 -0
  37. package/v2Components/HtmlEditor/components/ValidationErrorDisplay/index.js +70 -0
  38. package/v2Components/HtmlEditor/components/ValidationPanel/__tests__/index.test.js +98 -0
  39. package/v2Components/HtmlEditor/components/ValidationPanel/_validationPanel.scss +311 -0
  40. package/v2Components/HtmlEditor/components/ValidationPanel/index.js +297 -0
  41. package/v2Components/HtmlEditor/components/ValidationPanel/messages.js +57 -0
  42. package/v2Components/HtmlEditor/components/common/EditorContext.js +84 -0
  43. package/v2Components/HtmlEditor/components/common/__tests__/EditorContext.test.js +660 -0
  44. package/v2Components/HtmlEditor/constants.js +241 -0
  45. package/v2Components/HtmlEditor/hooks/__tests__/useEditorContent.test.js +450 -0
  46. package/v2Components/HtmlEditor/hooks/__tests__/useInAppContent.test.js +785 -0
  47. package/v2Components/HtmlEditor/hooks/__tests__/useLayoutState.test.js +580 -0
  48. package/v2Components/HtmlEditor/hooks/__tests__/useValidation.enhanced.test.js +768 -0
  49. package/v2Components/HtmlEditor/hooks/__tests__/useValidation.test.js +590 -0
  50. package/v2Components/HtmlEditor/hooks/useEditorContent.js +274 -0
  51. package/v2Components/HtmlEditor/hooks/useInAppContent.js +407 -0
  52. package/v2Components/HtmlEditor/hooks/useLayoutState.js +247 -0
  53. package/v2Components/HtmlEditor/hooks/useValidation.js +325 -0
  54. package/v2Components/HtmlEditor/index.js +29 -0
  55. package/v2Components/HtmlEditor/index.lazy.js +114 -0
  56. package/v2Components/HtmlEditor/messages.js +389 -0
  57. package/v2Components/HtmlEditor/utils/__tests__/contentSanitizer.test.js +741 -0
  58. package/v2Components/HtmlEditor/utils/__tests__/htmlValidator.enhanced.test.js +1042 -0
  59. package/v2Components/HtmlEditor/utils/__tests__/liquidTemplateSupport.test.js +515 -0
  60. package/v2Components/HtmlEditor/utils/__tests__/properSyntaxHighlighting.test.js +473 -0
  61. package/v2Components/HtmlEditor/utils/__tests__/simplePerformance.test.js +1109 -0
  62. package/v2Components/HtmlEditor/utils/__tests__/validationAdapter.test.js +240 -0
  63. package/v2Components/HtmlEditor/utils/contentSanitizer.js +433 -0
  64. package/v2Components/HtmlEditor/utils/htmlValidator.js +508 -0
  65. package/v2Components/HtmlEditor/utils/liquidTemplateSupport.js +524 -0
  66. package/v2Components/HtmlEditor/utils/properSyntaxHighlighting.js +163 -0
  67. package/v2Components/HtmlEditor/utils/simplePerformance.js +145 -0
  68. package/v2Components/HtmlEditor/utils/validationAdapter.js +130 -0
  69. package/v2Containers/EmailWrapper/components/HTMLEditorTesting.js +200 -0
  70. package/v2Containers/EmailWrapper/components/__tests__/HTMLEditorTesting.test.js +545 -0
  71. package/v2Containers/EmailWrapper/index.js +8 -1
  72. package/v2Containers/Templates/constants.js +8 -0
  73. package/v2Containers/Templates/index.js +56 -28
  74. package/v2Containers/Templates/tests/__snapshots__/index.test.js.snap +5 -14
  75. package/v2Containers/Whatsapp/constants.js +26 -2
  76. package/v2Containers/Whatsapp/index.js +4 -1
  77. package/v2Containers/Whatsapp/tests/index.test.js +460 -18
@@ -0,0 +1,304 @@
1
+ /**
2
+ * HTML Editor Main Styles
3
+ *
4
+ * Following project conventions with Cap UI variables and patterns
5
+ */
6
+
7
+ // Import Cap UI variables (correct path)
8
+ @import '~@capillarytech/cap-ui-library/styles/_variables.scss';
9
+
10
+ // Fullscreen modal header styling - using proper CSS specificity instead of !important
11
+ .html-editor-fullscreen {
12
+ .html-editor__header--fullscreen {
13
+ display: flex;
14
+ align-items: center;
15
+ background-color: $CAP_G10;
16
+ border-bottom: 0.0625rem solid $CAP_G08;
17
+ padding-right: 1rem;
18
+
19
+ // Device toggle takes available space
20
+ .device-toggle {
21
+ flex: 1;
22
+ }
23
+
24
+ // Toolbar styling in fullscreen mode
25
+ .editor-toolbar {
26
+ background-color: transparent;
27
+ border-bottom: none;
28
+ padding: 0;
29
+ min-height: 3.25rem;
30
+ height: 3.25rem;
31
+
32
+ // Right-align toolbar actions
33
+ &__right {
34
+ margin-left: auto;
35
+ }
36
+ }
37
+ }
38
+ }
39
+
40
+ .html-editor {
41
+ height: 37.5rem; // Fixed height instead of 100vh (600px = 37.5rem)
42
+ max-height: 80vh; // Responsive maximum height
43
+ display: flex;
44
+ flex-direction: column;
45
+ background-color: $CAP_WHITE;
46
+ font-family: $FONT_FAMILY;
47
+ border: 0.0625rem solid $CAP_G07;
48
+ border-radius: 0.25rem;
49
+ overflow: hidden;
50
+
51
+ &.fullscreen {
52
+ position: fixed;
53
+ top: 0;
54
+ left: 0;
55
+ right: 0;
56
+ bottom: 0;
57
+ z-index: 1050;
58
+ background-color: $CAP_WHITE;
59
+ border: none;
60
+ border-radius: 0;
61
+ // Override base height constraints to fill viewport
62
+ height: 100vh;
63
+ max-height: none;
64
+ min-height: unset;
65
+ }
66
+
67
+ // Loading state
68
+ &-loading {
69
+ display: flex;
70
+ align-items: center;
71
+ justify-content: center;
72
+ height: 25rem; // 400px = 25rem
73
+ background-color: $CAP_G09;
74
+ border-radius: 0.25rem;
75
+ }
76
+
77
+ // Main content area - seamless with toolbar
78
+ &-content {
79
+ flex: 1;
80
+ overflow: hidden;
81
+ background-color: $CAP_WHITE;
82
+ display: flex;
83
+ flex-direction: column;
84
+ }
85
+
86
+ // Validation Error Display - Full Width Below Split Container
87
+ &-validation {
88
+ margin-top: 1rem; // 16px = 1rem
89
+
90
+ // Ensure ErrorInfoNote fits well in the editor layout
91
+ .error-container {
92
+ width: 100%; // Full width instead of max-content
93
+ margin-top: 0;
94
+ margin-bottom: 0;
95
+ border-radius: 0.25rem;
96
+ }
97
+ }
98
+
99
+ // Split container - integrated design
100
+ &-split-container {
101
+ flex: 1;
102
+ display: flex;
103
+ background-color: $CAP_WHITE;
104
+ overflow: hidden;
105
+ border: none; // Remove borders for seamless look
106
+ }
107
+
108
+ // InApp variant specific styling
109
+ &--inapp {
110
+
111
+ // InApp variant has different header structure
112
+ .html-editor__header {
113
+ display: flex;
114
+ align-items: center;
115
+ background-color: $CAP_G10;
116
+ border-bottom: 0.0625rem solid $CAP_G08;
117
+ padding-right: 1rem;
118
+
119
+ // Device toggle takes available space
120
+ .device-toggle {
121
+ flex: 1;
122
+ }
123
+
124
+ // Toolbar styling in InApp variant
125
+ .editor-toolbar {
126
+ background-color: transparent;
127
+ border-bottom: none;
128
+ padding: 0;
129
+ min-height: 3.25rem; // 52px = 3.25rem
130
+ height: 3.25rem;
131
+
132
+ // Right-align toolbar actions
133
+ &__right {
134
+ margin-left: auto;
135
+ }
136
+ }
137
+ }
138
+ }
139
+
140
+
141
+ // Responsive design
142
+ @media (max-width: 768px) {
143
+ height: 31.25rem; // 500px = 31.25rem - Smaller height on tablets
144
+ max-height: 70vh;
145
+
146
+ &-split-container {
147
+ flex-direction: column;
148
+ }
149
+
150
+ // InApp variant responsive adjustments
151
+ &--inapp {
152
+ .html-editor__header {
153
+ flex-direction: column;
154
+ align-items: stretch;
155
+ padding: 0.75rem 1rem; // 12px 16px = 0.75rem 1rem
156
+
157
+ .device-toggle {
158
+ margin-bottom: 0.75rem; // 12px = 0.75rem
159
+ }
160
+
161
+ .editor-toolbar {
162
+ &__right {
163
+ margin-left: 0;
164
+ justify-content: flex-end;
165
+ }
166
+ }
167
+ }
168
+ }
169
+ }
170
+
171
+ @media (max-width: 576px) {
172
+ height: 25rem; // 400px = 25rem - Even smaller height on mobile
173
+ max-height: 60vh;
174
+
175
+ &-content {
176
+ padding: 0;
177
+ }
178
+
179
+ &-split-container {
180
+ border-radius: 0;
181
+ }
182
+ }
183
+
184
+ // Fullscreen modal styles
185
+ &-fullscreen {
186
+ height: 37.5rem; // 600px = 37.5rem
187
+ display: flex;
188
+ flex-direction: column;
189
+ background-color: $CAP_WHITE;
190
+
191
+ .html-editor-content-fullscreen {
192
+ flex: 1;
193
+ overflow: hidden;
194
+ background-color: $CAP_WHITE;
195
+ display: flex;
196
+ flex-direction: column;
197
+ }
198
+
199
+ .html-editor-split-container-fullscreen {
200
+ flex: 1;
201
+ display: flex;
202
+ background-color: $CAP_WHITE;
203
+ overflow: hidden;
204
+ border: none;
205
+ }
206
+
207
+ // Remove any default modal padding/margins
208
+ .editor-toolbar {
209
+ border-bottom: 0.0625rem solid $CAP_G07; // Add separator line in fullscreen
210
+ margin: 0;
211
+ padding-left: 1.5rem; // 24px = 1.5rem
212
+ padding-right: 1.5rem;
213
+ }
214
+
215
+ .editor-toolbar {
216
+ border-radius: 0; // Remove border radius in modal
217
+ }
218
+
219
+ .code-editor-pane {
220
+ .codemirror-wrapper {
221
+ height: 100%;
222
+ max-height: 70vh; // Larger height in fullscreen
223
+ }
224
+
225
+ &__content {
226
+ max-height: 70vh; // Larger height in fullscreen
227
+ }
228
+ }
229
+
230
+ .preview-pane {
231
+ max-height: 70vh; // Larger height in fullscreen
232
+
233
+ &__content {
234
+ max-height: 65vh; // Account for modal header
235
+ }
236
+
237
+ iframe {
238
+ height: 60vh; // Larger iframe in fullscreen
239
+ max-height: 60vh;
240
+ }
241
+ }
242
+ }
243
+ }
244
+
245
+ // Animation classes for smooth transitions
246
+ .html-editor-transition {
247
+ transition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1);
248
+ }
249
+
250
+ .html-editor-fade-enter {
251
+ opacity: 0;
252
+ }
253
+
254
+ .html-editor-fade-enter-active {
255
+ opacity: 1;
256
+ transition: opacity 0.3s ease-in;
257
+ }
258
+
259
+ .html-editor-fade-exit {
260
+ opacity: 1;
261
+ }
262
+
263
+ .html-editor-fade-exit-active {
264
+ opacity: 0;
265
+ transition: opacity 0.3s ease-out;
266
+ }
267
+
268
+ // Focus states and accessibility
269
+ .html-editor {
270
+ &:focus-within {
271
+ outline: 0.125rem solid map-get($CAP_PRIMARY, base); // 2px = 0.125rem
272
+ outline-offset: -0.125rem; // -2px = -0.125rem
273
+ }
274
+
275
+ // High contrast mode support
276
+ @media (prefers-contrast: high) {
277
+ border: 0.125rem solid $CAP_G01; // 2px = 0.125rem, #262626 ≈ $CAP_G01
278
+
279
+ &-split-container {
280
+ border: 0.0625rem solid $CAP_G06; // 1px = 0.0625rem, #d9d9d9 ≈ $CAP_G06
281
+ }
282
+ }
283
+
284
+ // Reduced motion support - !important is appropriate here for accessibility
285
+ @media (prefers-reduced-motion: reduce) {
286
+ * {
287
+ animation-duration: 0.01ms !important; // Override all animations for accessibility
288
+ animation-iteration-count: 1 !important; // Prevent looping animations
289
+ transition-duration: 0.01ms !important; // Minimize transition time
290
+ }
291
+ }
292
+ }
293
+
294
+ // Print styles
295
+ @media print {
296
+ .html-editor {
297
+ height: auto;
298
+
299
+ &-split-container {
300
+ flex-direction: column;
301
+ box-shadow: none;
302
+ }
303
+ }
304
+ }
@@ -0,0 +1,26 @@
1
+ /**
2
+ * HTMLEditor Lazy Loading Styles
3
+ *
4
+ * Styles for the lazy loading fallback component
5
+ */
6
+
7
+ // Import Cap UI variables for consistency
8
+ @import '~@capillarytech/cap-ui-library/styles/_variables.scss';
9
+
10
+ .html-editor-lazy-fallback {
11
+ display: flex;
12
+ justify-content: center;
13
+ align-items: center;
14
+ min-height: 25rem; // 400px = 25rem
15
+ background: $CAP_G11; // Light background similar to #fafbfc
16
+ border: 0.0625rem solid $CAP_G07; // 1px border similar to #dfe2e7
17
+ border-radius: 0.5rem; // 8px = 0.5rem
18
+ flex-direction: column;
19
+ gap: 1rem; // 16px = 1rem
20
+
21
+ &__message {
22
+ color: $CAP_G04; // Dark gray similar to #666
23
+ font-size: 0.875rem; // 14px = 0.875rem
24
+ text-align: center;
25
+ }
26
+ }
@@ -0,0 +1,376 @@
1
+ /**
2
+ * Code Editor Pane Styles
3
+ */
4
+
5
+ @import '~@capillarytech/cap-ui-library/styles/_variables.scss';
6
+
7
+ .code-editor-pane {
8
+ height: 100%;
9
+
10
+ // Dark theme CSS variables for CodeMirror
11
+ --editor-bg: #1e1e1e;
12
+ --editor-foreground: #d4d4d4;
13
+ --editor-focus-shadow: none;
14
+ --editor-focus-border: transparent;
15
+
16
+ &__header {
17
+ display: none;
18
+ }
19
+
20
+ &__title {
21
+ font-family: $FONT_FAMILY;
22
+ font-weight: 500;
23
+ font-size: 0.875rem;
24
+ line-height: 1.25rem;
25
+ color: $CAP_G01;
26
+ margin: 0;
27
+ white-space: nowrap;
28
+ }
29
+
30
+ &__actions {
31
+ display: flex;
32
+ align-items: center;
33
+ gap: 0.5rem;
34
+
35
+ .cap-button,
36
+ .ant-btn,
37
+ button {
38
+ color: map-get($CAP_PRIMARY, base);
39
+ border: none;
40
+ background: $CAP_WHITE;
41
+ border-radius: 0.25rem;
42
+ padding: 0.375rem 0.5rem;
43
+ font-size: 0.875rem;
44
+ font-family: $FONT_FAMILY;
45
+ font-weight: 500;
46
+ height: auto;
47
+ min-width: 5.9375rem;
48
+ display: flex;
49
+ align-items: center;
50
+ gap: 0.25rem;
51
+ box-shadow: 0 0 0.0625rem 0 rgba(9, 30, 66, 0.31), 0 0.25rem 0.5rem -0.125rem rgba(9, 30, 66, 0.25);
52
+ line-height: 1.25rem;
53
+ text-align: left;
54
+
55
+ &:hover {
56
+ background: $CAP_G09;
57
+ box-shadow: 0 0 0.0625rem 0 rgba(9, 30, 66, 0.31), 0 0.375rem 0.75rem -0.125rem rgba(9, 30, 66, 0.25);
58
+ color: map-get($CAP_PRIMARY, base);
59
+ border: none;
60
+ }
61
+
62
+ &:active,
63
+ &:focus {
64
+ background: $CAP_G08;
65
+ box-shadow: 0 0 0.0625rem 0 rgba(9, 30, 66, 0.31), 0 0.125rem 0.25rem -0.125rem rgba(9, 30, 66, 0.25);
66
+ color: map-get($CAP_PRIMARY, base);
67
+ border: none;
68
+ }
69
+
70
+ .anticon,
71
+ .cap-icon {
72
+ font-size: 1rem;
73
+ color: map-get($CAP_PRIMARY, base);
74
+ }
75
+
76
+ span {
77
+ font-size: 0.875rem;
78
+ font-weight: 500;
79
+ line-height: 1.25rem;
80
+ color: map-get($CAP_PRIMARY, base);
81
+ white-space: nowrap;
82
+ }
83
+
84
+ &:before,
85
+ &:after {
86
+ display: none;
87
+ }
88
+ }
89
+
90
+ .tooltip-add-label-container {
91
+
92
+ .cap-button,
93
+ .ant-btn {
94
+ color: map-get($CAP_PRIMARY, base);
95
+ background: $CAP_WHITE;
96
+ border: none;
97
+ box-shadow: 0 0 0.0625rem 0 rgba(9, 30, 66, 0.31), 0 0.25rem 0.5rem -0.125rem rgba(9, 30, 66, 0.25);
98
+ }
99
+ }
100
+
101
+ .cap-button-flat,
102
+ .cap-button-add {
103
+ background: $CAP_WHITE;
104
+ color: map-get($CAP_PRIMARY, base);
105
+ border: none;
106
+ }
107
+ }
108
+
109
+ &__content {
110
+ flex: 1;
111
+ display: flex;
112
+ flex-direction: column;
113
+ overflow: auto;
114
+ position: relative;
115
+ height: 100%;
116
+ max-height: 31.25rem;
117
+ background-color: $CAP_G01;
118
+ }
119
+
120
+ &__validation {
121
+ border-top: 0.0625rem solid $CAP_G04;
122
+ background: $CAP_G03;
123
+ max-height: 12.5rem;
124
+ overflow-y: auto;
125
+
126
+ .validation-panel {
127
+ border: none;
128
+ border-radius: 0;
129
+ background: transparent;
130
+ }
131
+ }
132
+
133
+ .cm-foldGutter {
134
+ width: 1rem;
135
+
136
+ .cm-gutterElement {
137
+ text-align: center;
138
+ cursor: pointer;
139
+ color: $CAP_G10;
140
+
141
+ &:hover {
142
+ color: $CAP_BLUE;
143
+ }
144
+ }
145
+ }
146
+
147
+ .cm-tooltip-autocomplete-enhanced {
148
+ background: $CAP_G02;
149
+ border: 0.0625rem solid $CAP_G04;
150
+ border-radius: 0.25rem;
151
+ box-shadow: 0 0.25rem 0.75rem rgba(0, 0, 0, 0.3);
152
+ font-family: monospace;
153
+ font-size: 0.8125rem;
154
+ max-height: 12.5rem;
155
+ overflow-y: auto;
156
+
157
+ .cm-completionIcon {
158
+ width: 1rem;
159
+ text-align: center;
160
+ margin-right: 0.5rem;
161
+ color: $CAP_BLUE;
162
+ }
163
+
164
+ .cm-completionLabel {
165
+ color: $CAP_G08;
166
+ font-weight: 500;
167
+ }
168
+
169
+ .cm-completionDetail {
170
+ color: $CAP_BLUE;
171
+ font-style: italic;
172
+ margin-left: auto;
173
+ }
174
+
175
+ li[aria-selected] {
176
+ background: map-get($CAP_PRIMARY, hover);
177
+ color: $CAP_WHITE;
178
+
179
+ .cm-completionIcon {
180
+ color: $CAP_WHITE;
181
+ }
182
+ }
183
+ }
184
+
185
+ .cm-search {
186
+ background: $CAP_G02;
187
+ border: 0.0625rem solid $CAP_G04;
188
+ border-radius: 0.25rem;
189
+ padding: 0.5rem;
190
+
191
+ input {
192
+ background: $CAP_G03;
193
+ border: 0.0625rem solid $CAP_G10;
194
+ color: $CAP_G08;
195
+ border-radius: 0.1875rem;
196
+ padding: 0.25rem 0.5rem;
197
+
198
+ &:focus {
199
+ outline: none;
200
+ border-color: $CAP_BLUE;
201
+ }
202
+ }
203
+
204
+ button {
205
+ background: $CAP_BLUE;
206
+ border: none;
207
+ color: $CAP_WHITE;
208
+ border-radius: 0.1875rem;
209
+ padding: 0.25rem 0.5rem;
210
+ margin-left: 0.25rem;
211
+ cursor: pointer;
212
+
213
+ &:hover {
214
+ background: $CAP_BLUE01;
215
+ }
216
+ }
217
+ }
218
+
219
+ * {
220
+ caret-color: $CAP_WHITE;
221
+ }
222
+
223
+ .codemirror-wrapper {
224
+ position: relative;
225
+ height: 100%;
226
+ max-height: 31.25rem;
227
+ background-color: $CAP_G01;
228
+ border-radius: 0;
229
+ overflow: hidden;
230
+ display: flex;
231
+
232
+ .code-editor-pane__actions {
233
+ position: absolute;
234
+ top: 0.5rem;
235
+ right: 0.5rem;
236
+ z-index: 20;
237
+
238
+ .cap-button,
239
+ .ant-btn,
240
+ button {
241
+ background: $CAP_WHITE;
242
+ color: map-get($CAP_PRIMARY, base);
243
+ border: none;
244
+ border-radius: 0.25rem;
245
+ padding: 0.375rem 0.5rem;
246
+ font-size: 0.875rem;
247
+ font-family: $FONT_FAMILY;
248
+ font-weight: 500;
249
+ min-width: 5.9375rem;
250
+ box-shadow: 0 0 0.0625rem 0 rgba(9, 30, 66, 0.31), 0 0.25rem 0.5rem -0.125rem rgba(9, 30, 66, 0.25);
251
+
252
+ &:hover {
253
+ background: $CAP_G09;
254
+ color: map-get($CAP_PRIMARY, base);
255
+ }
256
+
257
+ &:active {
258
+ background: $CAP_G08;
259
+ color: map-get($CAP_PRIMARY, base);
260
+ }
261
+ }
262
+ }
263
+
264
+ .codemirror-editor {
265
+ height: 100%;
266
+ background-color: var(--editor-bg, #1e1e1e);
267
+ flex: 1;
268
+
269
+ .cm-editor {
270
+ height: 100%;
271
+ border: none;
272
+ border-radius: 0;
273
+ background-color: var(--editor-bg, #1e1e1e);
274
+ color: var(--editor-foreground, #d4d4d4);
275
+ font-size: 0.875rem;
276
+ font-family: 'DM Mono', 'SF Mono', Monaco, 'Cascadia Code', 'Roboto Mono', Consolas, 'Courier New', monospace;
277
+
278
+ &.cm-focused {
279
+ outline: none;
280
+ box-shadow: var(--editor-focus-shadow, none);
281
+ border-color: var(--editor-focus-border, transparent);
282
+ }
283
+ }
284
+
285
+ .cm-content {
286
+ padding: 0.75rem;
287
+ font-family: 'DM Mono', 'SF Mono', Monaco, 'Cascadia Code', 'Roboto Mono', Consolas, 'Courier New', monospace;
288
+ font-size: 0.875rem;
289
+ line-height: 1.125rem;
290
+ background-color: var(--editor-bg, #1e1e1e);
291
+ color: var(--editor-foreground, #d4d4d4);
292
+ }
293
+
294
+ .cm-line {
295
+ padding: 0;
296
+ }
297
+
298
+ .cm-gutters {
299
+ background-color: var(--editor-gutter-bg, $CAP_G02);
300
+ border-right: 0.0625rem solid var(--editor-border, $CAP_G04);
301
+ color: var(--editor-gutter-foreground, $FONT_COLOR_02);
302
+ }
303
+
304
+ .cm-lineNumbers .cm-gutterElement {
305
+ padding: 0 0.5rem;
306
+ min-width: 2.5rem;
307
+ text-align: right;
308
+ font-size: 0.875rem;
309
+ line-height: 1.125rem;
310
+ color: var(--editor-gutter-foreground, $FONT_COLOR_02);
311
+ }
312
+
313
+ .cm-activeLine {
314
+ background-color: var(--editor-active-line-bg, rgba(map-get($CAP_PRIMARY, base), 0.05));
315
+ }
316
+
317
+ .cm-selectionBackground {
318
+ background-color: var(--editor-selection-bg, rgba(0, 123, 255, 0.3));
319
+ }
320
+
321
+ .cm-cursor,
322
+ .cm-cursor-primary,
323
+ .cm-cursor-secondary {
324
+ border-left: 0.1875rem solid var(--editor-cursor-color, $FONT_COLOR_01);
325
+ border-color: var(--editor-cursor-color, $FONT_COLOR_01);
326
+ }
327
+
328
+ &.cm-focused .cm-cursor,
329
+ &.cm-focused .cm-cursor-primary {
330
+ border-left: 0.1875rem solid var(--editor-cursor-color, $FONT_COLOR_01);
331
+ border-color: var(--editor-cursor-color, $FONT_COLOR_01);
332
+ }
333
+
334
+ .cm-line::after {
335
+ border-left: 0.1875rem solid var(--editor-cursor-color, $FONT_COLOR_01);
336
+ }
337
+
338
+ caret-color: var(--editor-cursor-color, $FONT_COLOR_01);
339
+ }
340
+
341
+ .codemirror-placeholder {
342
+ position: absolute;
343
+ top: 1rem;
344
+ left: 1rem;
345
+ color: $CAP_G06;
346
+ font-family: monospace;
347
+ font-size: 0.875rem;
348
+ line-height: 1.6;
349
+ pointer-events: none;
350
+ white-space: pre-line;
351
+ z-index: 1;
352
+ }
353
+ }
354
+
355
+ @media (max-width: 768px) {
356
+ .codemirror-wrapper {
357
+ .codemirror-editor {
358
+ .cm-content {
359
+ padding: 0.75rem;
360
+ font-size: 0.8125rem;
361
+ }
362
+
363
+ .cm-lineNumbers .cm-gutterElement {
364
+ padding: 0 0.375rem;
365
+ min-width: 1.75rem;
366
+ }
367
+ }
368
+
369
+ .codemirror-placeholder {
370
+ top: 0.75rem;
371
+ left: 0.75rem;
372
+ font-size: 0.8125rem;
373
+ }
374
+ }
375
+ }
376
+ }