@bikdotai/bik-widgets 1.0.0

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 (206) hide show
  1. package/.eslintrc +22 -0
  2. package/.eslintrc.js +19 -0
  3. package/.github/workflows/main.yml +293 -0
  4. package/.prettierignore +13 -0
  5. package/.prettierrc +10 -0
  6. package/README.md +128 -0
  7. package/cypress/apiHelper/endpoints.ts +21 -0
  8. package/cypress/apiHelper/executor.ts +42 -0
  9. package/cypress/e2e/bottomDrawer.cy.ts +49 -0
  10. package/cypress/e2e/directReward.cy.ts +67 -0
  11. package/cypress/e2e/scratchTheCard.cy.ts +68 -0
  12. package/cypress/e2e/stw.cy.ts +82 -0
  13. package/cypress/e2e/waRedirection.cy.ts +46 -0
  14. package/cypress/fixtures/payloads.ts +330 -0
  15. package/cypress/support/commands.ts +37 -0
  16. package/cypress/support/e2e.ts +20 -0
  17. package/cypress.staging.config.ts +23 -0
  18. package/jsconfig.json +6 -0
  19. package/localtest.sh +10 -0
  20. package/log-server.js +86 -0
  21. package/package.json +79 -0
  22. package/postcss.config.js +8 -0
  23. package/src/Globals.d.ts +2 -0
  24. package/src/assets/lottie/santa.json +11722 -0
  25. package/src/assets/svg/CalendarClockIcon.tsx +30 -0
  26. package/src/assets/svg/CalendarIcon.tsx +24 -0
  27. package/src/assets/svg/CheckIcon.tsx +17 -0
  28. package/src/assets/svg/ChevronIcon.tsx +21 -0
  29. package/src/assets/svg/Close.tsx +39 -0
  30. package/src/assets/svg/Confetti.tsx +140 -0
  31. package/src/assets/svg/Copy.tsx +26 -0
  32. package/src/assets/svg/DropdownCheckIcon.tsx +35 -0
  33. package/src/assets/svg/ErrorIcon.tsx +27 -0
  34. package/src/assets/svg/RadioIcon.tsx +25 -0
  35. package/src/assets/svg/UncheckedCheckboxIcon.tsx +28 -0
  36. package/src/assets/svg/UncheckedRadioIcon.tsx +26 -0
  37. package/src/assets/svg/info.tsx +30 -0
  38. package/src/assets/svg/qrcode.svg +14 -0
  39. package/src/bootstrap.tsx +8 -0
  40. package/src/components/CtaCard/index.tsx +37 -0
  41. package/src/components/CtaCard/preview.module.css +32 -0
  42. package/src/components/CtaCard/style.module.css +32 -0
  43. package/src/components/EmailInput/emailInputBox.tsx +95 -0
  44. package/src/components/Fab/index.tsx +224 -0
  45. package/src/components/Fab/preview.module.css +28 -0
  46. package/src/components/Fab/style.module.css +37 -0
  47. package/src/components/Icons/Call.tsx +26 -0
  48. package/src/components/Icons/Cross.tsx +24 -0
  49. package/src/components/Icons/Gmail.tsx +61 -0
  50. package/src/components/Icons/Instagram.tsx +60 -0
  51. package/src/components/Icons/LiveChat.tsx +43 -0
  52. package/src/components/Icons/Messenger.tsx +57 -0
  53. package/src/components/Icons/Send.tsx +22 -0
  54. package/src/components/Icons/Whatsapp.tsx +24 -0
  55. package/src/components/Shimmer/index.tsx +12 -0
  56. package/src/components/Shimmer/style.module.css +37 -0
  57. package/src/components/SmsInput/smsInputBox.tsx +135 -0
  58. package/src/components/UserDetailsV2/userDetailsV2.desktop.module.css +52 -0
  59. package/src/components/UserDetailsV2/userDetailsV2.mobile.module.css +52 -0
  60. package/src/components/UserDetailsV2/userDetailsV2.module.css +81 -0
  61. package/src/components/UserDetailsV2/userDetailsV2.tsx +527 -0
  62. package/src/components/WhatsappInput/Spinner.tsx +26 -0
  63. package/src/components/WhatsappInput/whatsappInput.module.css +106 -0
  64. package/src/components/WhatsappInput/whatsappInputBox.tsx +155 -0
  65. package/src/components/WhatsappInput/whatsappInputPreviewDesktop.module.css +71 -0
  66. package/src/components/WhatsappInput/whatsappInputPreviewMobile.module.css +65 -0
  67. package/src/components/checkbox/checkbox.module.css +19 -0
  68. package/src/components/checkbox/checkbox.tsx +88 -0
  69. package/src/components/countryCodePicker/countriesDropdown.module.css +77 -0
  70. package/src/components/countryCodePicker/countriesDropdown.tsx +81 -0
  71. package/src/components/couponDetails/coupon.module.css +208 -0
  72. package/src/components/couponDetails/coupon.tsx +210 -0
  73. package/src/components/couponDetails/couponPreviewDesktop.module.css +158 -0
  74. package/src/components/couponDetails/couponPreviewMobile.module.css +164 -0
  75. package/src/components/index.ts +3 -0
  76. package/src/components/inputComponents/Checkbox.module.css +197 -0
  77. package/src/components/inputComponents/Checkbox.tsx +85 -0
  78. package/src/components/inputComponents/DatePicker.module.css +565 -0
  79. package/src/components/inputComponents/DatePicker.tsx +278 -0
  80. package/src/components/inputComponents/Dropdown.module.css +796 -0
  81. package/src/components/inputComponents/Dropdown.tsx +630 -0
  82. package/src/components/inputComponents/InputBox.module.css +401 -0
  83. package/src/components/inputComponents/InputBox.tsx +209 -0
  84. package/src/components/selectedCountry/selectedCountry.module.css +76 -0
  85. package/src/components/selectedCountry/selectedCountry.tsx +76 -0
  86. package/src/components/selectedCountry/selectedCountryPreviewDesktop.module.css +56 -0
  87. package/src/components/selectedCountry/selectedCountryPreviewMobile.module.css +57 -0
  88. package/src/components/userDetailsForm/RenderCustomFields.tsx +333 -0
  89. package/src/components/userDetailsForm/userDetailsForm.tsx +675 -0
  90. package/src/hooks/index.ts +4 -0
  91. package/src/hooks/useExitIntent.ts +452 -0
  92. package/src/hooks/useIsMobile.tsx +21 -0
  93. package/src/hooks/useMessageEvent.ts +8 -0
  94. package/src/hooks/useTriggeredIntentDetails.ts +43 -0
  95. package/src/hooks/useUrlListerner.ts +30 -0
  96. package/src/hooks/useWebSocketLogger.ts +59 -0
  97. package/src/hooks/useWindowEvent.ts +8 -0
  98. package/src/icons/copyIcon.tsx +26 -0
  99. package/src/icons/crossIconDesktop.tsx +20 -0
  100. package/src/icons/crossIconMobile.tsx +20 -0
  101. package/src/index.html +30 -0
  102. package/src/index.ts +32 -0
  103. package/src/index.tsx +1 -0
  104. package/src/repo/widgetRepo.ts +21 -0
  105. package/src/types/customFields.ts +73 -0
  106. package/src/utilities/cookie.ts +70 -0
  107. package/src/utilities/customFieldTypeMapping.ts +67 -0
  108. package/src/utilities/customFieldValidation.ts +201 -0
  109. package/src/utilities/encryption.ts +21 -0
  110. package/src/utilities/exitIntentUtils.ts +31 -0
  111. package/src/utilities/global.css +11 -0
  112. package/src/utilities/languageUtilities.ts +235 -0
  113. package/src/utilities/localRunner.js +26 -0
  114. package/src/utilities/localRunner.ts +27 -0
  115. package/src/utilities/localStorage.ts +40 -0
  116. package/src/utilities/script.tsx +15 -0
  117. package/src/utilities/stringUtils.ts +5 -0
  118. package/src/utilities/styleUtils.ts +134 -0
  119. package/src/utilities/variables.ts +11 -0
  120. package/src/utilities/widgetUtils.js +342 -0
  121. package/src/utilities/widgetUtils.ts +313 -0
  122. package/src/widgets/BottomDrawer/config.ts +41 -0
  123. package/src/widgets/BottomDrawer/index.tsx +116 -0
  124. package/src/widgets/BottomDrawer/modal.tsx +286 -0
  125. package/src/widgets/BottomDrawer/preview.module.css +122 -0
  126. package/src/widgets/BottomDrawer/previewMobile.module.css +124 -0
  127. package/src/widgets/BottomDrawer/style.module.css +279 -0
  128. package/src/widgets/CaptivateBanner/captivateBanner.tsx +200 -0
  129. package/src/widgets/CaptivateBanner/config.ts +72 -0
  130. package/src/widgets/CaptivateBanner/index.tsx +204 -0
  131. package/src/widgets/CaptivateBanner/previewDesktop.module.css +51 -0
  132. package/src/widgets/CaptivateBanner/previewMobile.module.css +51 -0
  133. package/src/widgets/CaptivateBanner/style.module.css +77 -0
  134. package/src/widgets/CaptivateBanner/utils.ts +104 -0
  135. package/src/widgets/CentrallyAlignedPopup/config.ts +42 -0
  136. package/src/widgets/CentrallyAlignedPopup/index.tsx +109 -0
  137. package/src/widgets/CentrallyAlignedPopup/modal.tsx +269 -0
  138. package/src/widgets/CentrallyAlignedPopup/preview.module.css +153 -0
  139. package/src/widgets/CentrallyAlignedPopup/previewMobile.module.css +153 -0
  140. package/src/widgets/CentrallyAlignedPopup/style.module.css +283 -0
  141. package/src/widgets/DirectReward/components/couponDetails.tsx +265 -0
  142. package/src/widgets/DirectReward/components/userDetails.tsx +117 -0
  143. package/src/widgets/DirectReward/config.ts +186 -0
  144. package/src/widgets/DirectReward/directReward.tsx +350 -0
  145. package/src/widgets/DirectReward/index.tsx +579 -0
  146. package/src/widgets/DirectReward/previewStyles/thankYouPreviewDesktop.module.css +276 -0
  147. package/src/widgets/DirectReward/previewStyles/thankYouPreviewMobile.module.css +303 -0
  148. package/src/widgets/DirectReward/previewStyles/userDetailsPreviewDesktop.module.css +511 -0
  149. package/src/widgets/DirectReward/previewStyles/userDetailsPreviewMobile.module.css +462 -0
  150. package/src/widgets/DirectReward/style.module.css +836 -0
  151. package/src/widgets/ExitIntentHook.tsx +28 -0
  152. package/src/widgets/STW/api.ts +70 -0
  153. package/src/widgets/STW/components/svgFactory.tsx +44 -0
  154. package/src/widgets/STW/config.ts +193 -0
  155. package/src/widgets/STW/context.ts +7 -0
  156. package/src/widgets/STW/couponDetails.tsx +121 -0
  157. package/src/widgets/STW/index.tsx +733 -0
  158. package/src/widgets/STW/previewStyles/thankyouPreviewDesktop.module.css +215 -0
  159. package/src/widgets/STW/previewStyles/thankyouPreviewMobile.module.css +205 -0
  160. package/src/widgets/STW/previewStyles/userInputsPreviewDesktop.module.css +732 -0
  161. package/src/widgets/STW/previewStyles/userInputsPreviewMobile.module.css +661 -0
  162. package/src/widgets/STW/previewStyles/wheelPreviewDesktop.module.css +498 -0
  163. package/src/widgets/STW/previewStyles/wheelPreviewMobile.module.css +497 -0
  164. package/src/widgets/STW/stw1.tsx +119 -0
  165. package/src/widgets/STW/stw2Components/wheelDesign.tsx +183 -0
  166. package/src/widgets/STW/stw2Pages/couponDetails.tsx +72 -0
  167. package/src/widgets/STW/stw2Pages/stw2.tsx +212 -0
  168. package/src/widgets/STW/stw2Pages/style.module.css +1226 -0
  169. package/src/widgets/STW/stw2Pages/userDetails.tsx +86 -0
  170. package/src/widgets/STW/stw2Pages/wheel.tsx +117 -0
  171. package/src/widgets/STW/stw2PreviewStyles/thankyouPreviewDesktop.module.css +835 -0
  172. package/src/widgets/STW/stw2PreviewStyles/thankyouPreviewMobile.module.css +787 -0
  173. package/src/widgets/STW/stw2PreviewStyles/userInputsPreviewDesktop.module.css +867 -0
  174. package/src/widgets/STW/stw2PreviewStyles/userInputsPreviewMobile.module.css +798 -0
  175. package/src/widgets/STW/stw2PreviewStyles/wheelPreviewDesktop.module.css +572 -0
  176. package/src/widgets/STW/stw2PreviewStyles/wheelPreviewMobile.module.css +559 -0
  177. package/src/widgets/STW/style.module.css +901 -0
  178. package/src/widgets/STW/userDetails.tsx +150 -0
  179. package/src/widgets/STW/utility.ts +664 -0
  180. package/src/widgets/STW/wheel.tsx +304 -0
  181. package/src/widgets/ScratchCard/ScratchOff/scratchOff.tsx +157 -0
  182. package/src/widgets/ScratchCard/config.ts +152 -0
  183. package/src/widgets/ScratchCard/globalStyle.module.css +931 -0
  184. package/src/widgets/ScratchCard/index.tsx +546 -0
  185. package/src/widgets/ScratchCard/modal.tsx +225 -0
  186. package/src/widgets/ScratchCard/preview.module.css +250 -0
  187. package/src/widgets/ScratchCard/previewMobile.module.css +247 -0
  188. package/src/widgets/ScratchCard/previewStyles/userDetailsPreviewDesktop.module.css +537 -0
  189. package/src/widgets/ScratchCard/previewStyles/userDetailsPreviewMobile.module.css +463 -0
  190. package/src/widgets/ScratchCard/style.module.css +220 -0
  191. package/src/widgets/ShopifyForm/config.ts +168 -0
  192. package/src/widgets/ShopifyForm/index.tsx +214 -0
  193. package/src/widgets/ShopifyForm/previewDesktop.module.css +117 -0
  194. package/src/widgets/ShopifyForm/previewMobile.module.css +131 -0
  195. package/src/widgets/ShopifyForm/shopifyForm.tsx +445 -0
  196. package/src/widgets/ShopifyForm/style.module.css +161 -0
  197. package/src/widgets/SingleButtonRedirection/config.ts +47 -0
  198. package/src/widgets/SingleButtonRedirection/index.tsx +121 -0
  199. package/src/widgets/WebStories/config.ts +105 -0
  200. package/src/widgets/WebStories/index.css +3 -0
  201. package/src/widgets/WebStories/index.tsx +282 -0
  202. package/src/widgets/WebStories/style.module.css +26 -0
  203. package/src/widgets/index.tsx +3 -0
  204. package/src/widgets/utility.ts +31 -0
  205. package/tsconfig.json +12 -0
  206. package/webpack.config.js +239 -0
@@ -0,0 +1,401 @@
1
+ .bik-inputBox__container {
2
+ /* Colors */
3
+ --bik-inputBox-border-color: #e0e0e0;
4
+ --bik-inputBox-bg-color: rgba(255, 255, 255, 0.3);
5
+ --bik-inputBox-text-color: #1f2937;
6
+ --bik-inputBox-label-color: #6b7280;
7
+ --bik-inputBox-placeholder-color: #9ca3af;
8
+ --bik-inputBox-disabled-color: #9ca3af;
9
+ --bik-inputBox-error-color: #ef4444;
10
+ --bik-inputBox-error-border-color: #b92321;
11
+ --bik-inputBox-warning-color: #f59e0b;
12
+
13
+ /* Layout & Spacing */
14
+ --bik-inputBox-border-radius: 8px;
15
+ --bik-inputBox-min-height-desktop: 56px;
16
+ --bik-inputBox-min-height-mobile: 48px;
17
+ --bik-inputBox-min-height-preview: 20px;
18
+
19
+ /* Padding */
20
+ --bik-inputBox-padding-desktop: 24px 18px 12px;
21
+ --bik-inputBox-padding-mobile: 16px 18px 2px 16px;
22
+ --bik-inputBox-padding-preview: 2px 4px;
23
+ --bik-inputBox-label-padding-desktop: 18px;
24
+ --bik-inputBox-label-padding-mobile: 14px;
25
+ --bik-inputBox-label-padding-preview: 2px;
26
+
27
+ /* Animations & Transitions */
28
+ --bik-inputBox-transition: all 0.3s cubic-bezier(0.25, 0.46, 0.45, 0.94);
29
+ --bik-inputBox-transition-fast: all 0.2s ease;
30
+
31
+ /* Shadows */
32
+ --bik-inputBox-shadow-hover: 0 1px 2px rgba(0, 0, 0, 0.03);
33
+ --bik-inputBox-shadow-focus: 0 1px 3px
34
+ color-mix(
35
+ in srgb,
36
+ var(--bik-focus-color, var(--bik-inputBox-border-color)) 6%,
37
+ transparent
38
+ );
39
+ --bik-inputBox-shadow-error: 0 1px 3px rgba(185, 35, 33, 0.06);
40
+ --bik-inputBox-shadow-error-hover: 0 1px 4px rgba(185, 35, 33, 0.08);
41
+
42
+ position: relative;
43
+ margin: 0;
44
+ width: 100%;
45
+ }
46
+
47
+ .bik-inputBox__inputWrapper {
48
+ position: relative;
49
+ display: flex;
50
+ align-items: center;
51
+ background: var(--bik-inputBox-bg-color);
52
+ border: 1px solid var(--bik-inputBox-border-color);
53
+ border-radius: var(--bik-inputBox-border-radius);
54
+ overflow: hidden;
55
+ transition: var(--bik-inputBox-transition);
56
+ min-height: var(--bik-inputBox-min-height-desktop);
57
+ }
58
+
59
+ .bik-inputBox__inputWrapper::before {
60
+ content: '';
61
+ position: absolute;
62
+ inset: 0;
63
+ background: linear-gradient(135deg, transparent, rgba(255, 255, 255, 0.1));
64
+ border-radius: inherit;
65
+ pointer-events: none;
66
+ }
67
+
68
+ .bik-inputBox__inputWrapper:hover {
69
+ box-shadow: var(--bik-inputBox-shadow-hover);
70
+ }
71
+
72
+ .bik-inputBox__inputWrapper--focused {
73
+ box-shadow: var(--bik-inputBox-shadow-focus);
74
+ }
75
+
76
+ .bik-inputBox__inputWrapper--error {
77
+ border-color: var(--bik-inputBox-error-border-color);
78
+ box-shadow: var(--bik-inputBox-shadow-error);
79
+ }
80
+
81
+ .bik-inputBox__inputWrapper--error:hover,
82
+ .bik-inputBox__inputWrapper--error.bik-inputBox__inputWrapper--focused {
83
+ box-shadow: var(--bik-inputBox-shadow-error-hover);
84
+ }
85
+
86
+ .bik-inputBox__inputWrapper--disabled,
87
+ .bik-inputBox__inputWrapper--disabled:hover {
88
+ background: var(--bik-inputBox-bg-color);
89
+ border-color: var(--bik-inputBox-border-color);
90
+ box-shadow: none;
91
+ transform: none;
92
+ }
93
+
94
+ .bik-inputBox__input {
95
+ padding: var(--bik-inputBox-padding-desktop) !important;
96
+ margin: 0 !important;
97
+ border: none !important;
98
+ background: transparent !important;
99
+ font-weight: 400 !important;
100
+ font-size: 14px !important;
101
+ line-height: 1.5 !important;
102
+ color: var(--bik-inputBox-text-color);
103
+ width: 100%;
104
+ box-sizing: border-box;
105
+ outline: none;
106
+ transition: var(--bik-inputBox-transition-fast);
107
+ box-shadow: none !important;
108
+ }
109
+
110
+ .bik-inputBox__input[type='number'] {
111
+ appearance: textfield;
112
+ }
113
+
114
+ .bik-inputBox__input[type='number']::-webkit-outer-spin-button,
115
+ .bik-inputBox__input[type='number']::-webkit-inner-spin-button {
116
+ appearance: none;
117
+ margin: 0;
118
+ }
119
+
120
+ .bik-inputBox__input:is(textarea) {
121
+ min-height: 56px;
122
+ }
123
+
124
+ .bik-inputBox__input::placeholder,
125
+ .bik-inputBox__input:focus::placeholder {
126
+ color: var(--bik-inputBox-placeholder-color);
127
+ opacity: 1;
128
+ }
129
+
130
+ .bik-inputBox__input:disabled {
131
+ color: var(--bik-inputBox-disabled-color);
132
+ cursor: not-allowed;
133
+ }
134
+
135
+ .bik-inputBox__label {
136
+ position: absolute;
137
+ left: var(--bik-inputBox-label-padding-desktop);
138
+ top: 50%;
139
+ transform: translateY(-50%);
140
+ font-weight: 400;
141
+ font-size: 14px;
142
+ color: var(--bik-inputBox-label-color);
143
+ background: transparent;
144
+ padding: 0 8px;
145
+ margin-left: -8px;
146
+ max-width: calc(100% - 40px);
147
+ white-space: nowrap;
148
+ overflow: hidden;
149
+ text-overflow: ellipsis;
150
+ pointer-events: none;
151
+ transition: var(--bik-inputBox-transition);
152
+ z-index: 2;
153
+ }
154
+
155
+ .bik-inputBox__label--multiline {
156
+ top: 24px;
157
+ transform: translateY(0);
158
+ }
159
+
160
+ .bik-inputBox__label--floated,
161
+ .bik-inputBox__input:focus + .bik-inputBox__label,
162
+ .bik-inputBox__input:not(:placeholder-shown) + .bik-inputBox__label,
163
+ .bik-inputBox__label--hasValue {
164
+ top: 8px;
165
+ transform: translateY(0);
166
+ font-size: 11px;
167
+ font-weight: 400;
168
+ background: transparent;
169
+ }
170
+
171
+ .bik-inputBox__label--floated {
172
+ font-weight: 500;
173
+ color: var(--bik-inputBox-placeholder-color);
174
+ }
175
+
176
+ .bik-inputBox__input:focus + .bik-inputBox__label {
177
+ color: var(--bik-inputBox-placeholder-color);
178
+ }
179
+
180
+ .bik-inputBox__label--error {
181
+ color: var(--bik-inputBox-error-color) !important;
182
+ }
183
+
184
+ .bik-inputBox__label--disabled {
185
+ color: var(--bik-inputBox-disabled-color) !important;
186
+ background: transparent;
187
+ }
188
+
189
+ .bik-inputBox__required {
190
+ color: var(--bik-inputBox-error-color);
191
+ margin-left: 2px;
192
+ font-weight: 500;
193
+ }
194
+
195
+ .bik-inputBox__error {
196
+ color: var(--bik-inputBox-error-color);
197
+ font-weight: 400;
198
+ font-size: 11px;
199
+ margin: 4px 0 0 6px;
200
+ display: flex;
201
+ align-items: center;
202
+ gap: 4px;
203
+ animation: bik-slideInError 0.3s ease-out;
204
+ }
205
+
206
+ .bik-inputBox__errorIcon {
207
+ width: 12px;
208
+ height: 12px;
209
+ flex-shrink: 0;
210
+ display: flex;
211
+ align-items: center;
212
+ justify-content: center;
213
+ }
214
+
215
+ .bik-inputBox__characterCount {
216
+ position: absolute;
217
+ right: 20px;
218
+ top: 8px;
219
+ font-weight: 400;
220
+ font-size: 11px;
221
+ color: var(--bik-inputBox-placeholder-color);
222
+ background: transparent;
223
+ opacity: 0;
224
+ transform: translateY(8px);
225
+ transition: var(--bik-inputBox-transition);
226
+ pointer-events: none;
227
+ z-index: 3;
228
+ padding: 0 4px;
229
+ }
230
+
231
+ .bik-inputBox__characterCount--visible {
232
+ opacity: 1;
233
+ transform: translateY(0);
234
+ }
235
+
236
+ .bik-inputBox__characterCount--warning {
237
+ color: var(--bik-inputBox-warning-color);
238
+ }
239
+
240
+ .bik-inputBox__characterCount--error {
241
+ color: var(--bik-inputBox-error-color);
242
+ }
243
+
244
+ @keyframes bik-slideInError {
245
+ from {
246
+ opacity: 0;
247
+ transform: translateY(-4px);
248
+ }
249
+ to {
250
+ opacity: 1;
251
+ transform: translateY(0);
252
+ }
253
+ }
254
+
255
+ @media (prefers-reduced-motion: reduce) {
256
+ .bik-inputBox__container *,
257
+ .bik-inputBox__container *::before,
258
+ .bik-inputBox__container *::after {
259
+ transition: none !important;
260
+ animation: none !important;
261
+ }
262
+ }
263
+
264
+ @media (prefers-contrast: high) {
265
+ .bik-inputBox__inputWrapper {
266
+ border-width: 3px;
267
+ }
268
+
269
+ .bik-inputBox__label {
270
+ font-weight: 600;
271
+ }
272
+ }
273
+
274
+ .bik-inputBox__container[data-mode='preview'] .bik-inputBox__inputWrapper {
275
+ min-height: var(--bik-inputBox-min-height-preview);
276
+ box-shadow: none;
277
+ }
278
+
279
+ .bik-inputBox__container[data-mode='preview'] .bik-inputBox__input {
280
+ padding: var(--bik-inputBox-padding-preview) !important;
281
+ font-size: 8px;
282
+ line-height: 1.2;
283
+ }
284
+
285
+ .bik-inputBox__container[data-mode='preview']
286
+ .bik-inputBox__input:is(textarea) {
287
+ min-height: var(--bik-inputBox-min-height-preview);
288
+ max-height: 25px;
289
+ resize: none;
290
+ padding: 2px 4px;
291
+ line-height: 1.1;
292
+ }
293
+
294
+ .bik-inputBox__container[data-mode='preview'] .bik-inputBox__label--multiline {
295
+ top: 9px;
296
+ }
297
+
298
+ .bik-inputBox__container[data-mode='preview'] .bik-inputBox__label {
299
+ left: 4px;
300
+ font-size: 7px;
301
+ line-height: 1.2;
302
+ max-width: calc(100% - 2px);
303
+ }
304
+
305
+ .bik-inputBox__container[data-mode='preview'] .bik-inputBox__label--floated,
306
+ .bik-inputBox__container[data-mode='preview']
307
+ .bik-inputBox__input:focus
308
+ + .bik-inputBox__label,
309
+ .bik-inputBox__container[data-mode='preview']
310
+ .bik-inputBox__input:not(:placeholder-shown)
311
+ + .bik-inputBox__label,
312
+ .bik-inputBox__container[data-mode='preview'] .bik-inputBox__label--hasValue {
313
+ top: 2px;
314
+ font-size: 6px;
315
+ }
316
+
317
+ .bik-inputBox__container[data-mode='preview'] .bik-inputBox__error {
318
+ font-size: 6px;
319
+ margin: 2px 0 0 2px;
320
+ }
321
+
322
+ .bik-inputBox__container[data-mode='preview'] .bik-inputBox__errorIcon {
323
+ width: 8px;
324
+ height: 8px;
325
+ }
326
+
327
+ .bik-inputBox__container[data-mode='preview'] .bik-inputBox__characterCount {
328
+ font-size: 6px;
329
+ right: 8px;
330
+ top: 2px;
331
+ }
332
+
333
+ @media (max-width: 768px) {
334
+ .bik-inputBox__input {
335
+ font-size: 14px !important;
336
+ padding: var(--bik-inputBox-padding-mobile) !important;
337
+ }
338
+
339
+ .bik-inputBox__label {
340
+ left: var(--bik-inputBox-label-padding-mobile);
341
+ margin-left: -6px;
342
+ }
343
+
344
+ .bik-inputBox__inputWrapper {
345
+ min-height: var(--bik-inputBox-min-height-mobile);
346
+ }
347
+
348
+ .bik-inputBox__container[data-mode='preview'] .bik-inputBox__inputWrapper {
349
+ min-height: var(--bik-inputBox-min-height-preview);
350
+ box-shadow: none;
351
+ }
352
+
353
+ .bik-inputBox__container[data-mode='preview'] .bik-inputBox__input {
354
+ padding: var(--bik-inputBox-padding-preview);
355
+ font-size: 7px;
356
+ line-height: 1.2;
357
+ }
358
+
359
+ .bik-inputBox__container[data-mode='preview']
360
+ .bik-inputBox__input:is(textarea) {
361
+ min-height: var(--bik-inputBox-min-height-preview);
362
+ max-height: 35px;
363
+ resize: none;
364
+ padding: 2px 4px;
365
+ line-height: 1.1;
366
+ }
367
+
368
+ .bik-inputBox__container[data-mode='preview'] .bik-inputBox__label {
369
+ left: var(--bik-inputBox-label-padding-preview);
370
+ font-size: 6px;
371
+ line-height: 1.2;
372
+ }
373
+
374
+ .bik-inputBox__container[data-mode='preview'] .bik-inputBox__label--floated,
375
+ .bik-inputBox__container[data-mode='preview']
376
+ .bik-inputBox__input:focus
377
+ + .bik-inputBox__label,
378
+ .bik-inputBox__container[data-mode='preview']
379
+ .bik-inputBox__input:not(:placeholder-shown)
380
+ + .bik-inputBox__label,
381
+ .bik-inputBox__container[data-mode='preview'] .bik-inputBox__label--hasValue {
382
+ top: 1px;
383
+ font-size: 5px;
384
+ }
385
+
386
+ .bik-inputBox__container[data-mode='preview'] .bik-inputBox__error {
387
+ font-size: 5px;
388
+ margin: 1px 0 0 1px;
389
+ }
390
+
391
+ .bik-inputBox__container[data-mode='preview'] .bik-inputBox__errorIcon {
392
+ width: 6px;
393
+ height: 6px;
394
+ }
395
+
396
+ .bik-inputBox__container[data-mode='preview'] .bik-inputBox__characterCount {
397
+ font-size: 5px;
398
+ right: 6px;
399
+ top: 1px;
400
+ }
401
+ }
@@ -0,0 +1,209 @@
1
+ import React, { useState } from 'react';
2
+ import styles from './InputBox.module.css';
3
+ import { ErrorIcon } from '../../assets/svg/ErrorIcon';
4
+
5
+ export type InputType = 'text' | 'email' | 'number';
6
+
7
+ export interface InputBoxProps {
8
+ id?: string;
9
+ value: string;
10
+ onChange: (value: string) => void;
11
+ inputType?: InputType;
12
+ labelText?: string;
13
+ isMultiline?: boolean;
14
+ isRequired?: boolean;
15
+ errorMessage?: string;
16
+ minValue?: number;
17
+ maxValue?: number;
18
+ stepValue?: number;
19
+ isDisabled?: boolean;
20
+ maxCharacters?: number;
21
+ textareaRows?: number;
22
+ inputHeight?: number;
23
+ fontColour?: string;
24
+ backgroundColor?: string;
25
+ isPreview?: boolean;
26
+ }
27
+
28
+ export const InputBox: React.FC<InputBoxProps> = ({
29
+ id,
30
+ value,
31
+ onChange,
32
+ inputType = 'text',
33
+ isDisabled = false,
34
+ isRequired = false,
35
+ maxCharacters,
36
+ labelText,
37
+ errorMessage,
38
+ isMultiline = false,
39
+ textareaRows = 3,
40
+ minValue,
41
+ maxValue,
42
+ stepValue,
43
+ inputHeight,
44
+ fontColour,
45
+ isPreview = false,
46
+ }) => {
47
+ const [isFocused, setIsFocused] = useState(false);
48
+
49
+ const hasValue = value.length > 0;
50
+ const shouldFloatLabel = isFocused || hasValue;
51
+ const displayError = errorMessage;
52
+ const characterPercentage = maxCharacters
53
+ ? (value.length / maxCharacters) * 100
54
+ : 0;
55
+
56
+ const handleChange = (
57
+ e: React.ChangeEvent<HTMLInputElement | HTMLTextAreaElement>,
58
+ ) => {
59
+ let newValue = e.target.value;
60
+ if (inputType === 'number' && newValue.trim()) {
61
+ const numValue = parseFloat(newValue);
62
+ if (!isNaN(numValue)) {
63
+ if (minValue !== undefined && numValue < minValue) {
64
+ newValue = minValue.toString();
65
+ } else if (maxValue !== undefined && numValue > maxValue) {
66
+ newValue = maxValue.toString();
67
+ }
68
+ }
69
+ }
70
+ onChange(newValue);
71
+ };
72
+
73
+ const handleFocus = () => {
74
+ setIsFocused(true);
75
+ };
76
+
77
+ const handleBlur = () => {
78
+ setIsFocused(false);
79
+ };
80
+
81
+ const getBikCharacterCountClasses = () => {
82
+ if (!maxCharacters) return '';
83
+
84
+ const shouldShow = isFocused || hasValue;
85
+
86
+ return [
87
+ styles['bik-inputBox__characterCount'],
88
+ shouldShow && styles['bik-inputBox__characterCount--visible'],
89
+ characterPercentage >= 100 &&
90
+ styles['bik-inputBox__characterCount--error'],
91
+ characterPercentage >= 0.75 * 100 &&
92
+ characterPercentage < 100 &&
93
+ styles['bik-inputBox__characterCount--warning'],
94
+ ]
95
+ .filter(Boolean)
96
+ .join(' ');
97
+ };
98
+
99
+ const getBikWrapperClasses = () => {
100
+ return [
101
+ styles['bik-inputBox__inputWrapper'],
102
+ isFocused && styles['bik-inputBox__inputWrapper--focused'],
103
+ displayError && styles['bik-inputBox__inputWrapper--error'],
104
+ isDisabled && styles['bik-inputBox__inputWrapper--disabled'],
105
+ ]
106
+ .filter(Boolean)
107
+ .join(' ');
108
+ };
109
+
110
+ const getBikLabelClasses = () => {
111
+ return [
112
+ styles['bik-inputBox__label'],
113
+ isMultiline && styles['bik-inputBox__label--multiline'],
114
+ shouldFloatLabel && styles['bik-inputBox__label--floated'],
115
+ displayError && styles['bik-inputBox__label--error'],
116
+ isDisabled && styles['bik-inputBox__label--disabled'],
117
+ hasValue && styles['bik-inputBox__label--hasValue'],
118
+ ]
119
+ .filter(Boolean)
120
+ .join(' ');
121
+ };
122
+
123
+ return (
124
+ <div
125
+ className={styles['bik-inputBox__container']}
126
+ data-mode={isPreview ? 'preview' : 'default'}
127
+ >
128
+ <div
129
+ className={getBikWrapperClasses()}
130
+ style={{
131
+ borderColor: displayError ? '#b92321' : undefined,
132
+ paddingTop: isMultiline ? '24px' : undefined,
133
+ }}
134
+ >
135
+ {isMultiline ? (
136
+ <textarea
137
+ id={id}
138
+ value={value}
139
+ onChange={handleChange}
140
+ onFocus={handleFocus}
141
+ onBlur={handleBlur}
142
+ placeholder={' '}
143
+ disabled={isDisabled}
144
+ required={isRequired}
145
+ maxLength={maxCharacters}
146
+ rows={textareaRows}
147
+ className={styles['bik-inputBox__input']}
148
+ style={{
149
+ resize: 'none',
150
+ minHeight: 'auto',
151
+ paddingTop: 0,
152
+ color: fontColour,
153
+ }}
154
+ />
155
+ ) : (
156
+ <input
157
+ id={id}
158
+ type={inputType}
159
+ value={value}
160
+ onChange={handleChange}
161
+ onFocus={handleFocus}
162
+ onBlur={handleBlur}
163
+ placeholder={' '}
164
+ disabled={isDisabled}
165
+ required={isRequired}
166
+ maxLength={maxCharacters}
167
+ min={minValue}
168
+ max={maxValue}
169
+ step={stepValue}
170
+ className={styles['bik-inputBox__input']}
171
+ style={{
172
+ height: inputHeight ? `${inputHeight}px` : undefined,
173
+ color: fontColour,
174
+ }}
175
+ />
176
+ )}
177
+
178
+ {labelText && (
179
+ <div
180
+ className={getBikLabelClasses()}
181
+ style={{
182
+ color: fontColour,
183
+ }}
184
+ >
185
+ {labelText}
186
+ {isRequired && (
187
+ <span className={styles['bik-inputBox__required']}>*</span>
188
+ )}
189
+ </div>
190
+ )}
191
+
192
+ {maxCharacters && (
193
+ <div className={getBikCharacterCountClasses()}>
194
+ {value.length}/{maxCharacters}
195
+ </div>
196
+ )}
197
+ </div>
198
+
199
+ {displayError && (
200
+ <div className={styles['bik-inputBox__error']}>
201
+ <div className={styles['bik-inputBox__errorIcon']}>
202
+ <ErrorIcon size={12} />
203
+ </div>
204
+ {displayError}
205
+ </div>
206
+ )}
207
+ </div>
208
+ );
209
+ };
@@ -0,0 +1,76 @@
1
+ .bikStwCountryCodePicker {
2
+ border-radius: 8px;
3
+ border-width: 1px;
4
+ border-style: solid;
5
+ align-items: center;
6
+ height: 34px;
7
+ border-color: #e0e0e0;
8
+ gap: 8px;
9
+ display: flex;
10
+ flex-direction: row;
11
+ font-family: inherit;
12
+ background-color: rgba(256, 256, 256, 0.3);
13
+ cursor: pointer;
14
+ }
15
+
16
+ .bikStwCountryCodeContainer {
17
+ gap: 8px;
18
+ display: flex;
19
+ align-items: center;
20
+ flex-direction: row;
21
+ font-family: inherit;
22
+ }
23
+
24
+ .bikStwCountryFlag {
25
+ width: 24px;
26
+ height: auto;
27
+ }
28
+
29
+ .bikStwH2 {
30
+ font-family: inherit;
31
+ font-style: normal;
32
+ font-weight: 400;
33
+ font-size: 14px;
34
+ line-height: 20px;
35
+ font-feature-settings:
36
+ 'tnum' on,
37
+ 'lnum' on,
38
+ 'case' on,
39
+ 'ss04' on;
40
+ color: #212121;
41
+ margin-bottom: 8px;
42
+ }
43
+
44
+ .bikStwDownArrow {
45
+ width: 0;
46
+ height: 0;
47
+ border-left: 5px solid transparent;
48
+ border-right: 5px solid transparent;
49
+ border-top: 7px solid #616161;
50
+ font-size: 0;
51
+ line-height: 0;
52
+ float: left;
53
+ display: block !important;
54
+ }
55
+
56
+ @media only screen and (max-width: 768px) {
57
+ .bikStwH2 {
58
+ font-size: 10px;
59
+ }
60
+
61
+ .bikStwCountryCodePicker {
62
+ gap: 6px;
63
+ height: 30px;
64
+ }
65
+
66
+ .bikStwDownArrow {
67
+ border-left: 3px solid transparent;
68
+ border-right: 3px solid transparent;
69
+ border-top: 5px solid #616161;
70
+ }
71
+
72
+ .bikStwCountryFlag {
73
+ width: 22px;
74
+ height: auto;
75
+ }
76
+ }