@idonatedev/idonate-sdk 1.2.0-dev18 → 1.2.0-dev19

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.
@@ -21,11 +21,12 @@ const tokenizer_utils_1 = require("./tokenizer-utils");
21
21
  const SPREEDLY_SCRIPT_URL = 'https://core.spreedly.com/iframe/iframe-v1.min.js';
22
22
  const SPREEDLY_SCRIPT_ID = 'spreedly-iframe-script';
23
23
  class SpreedlyTokenizer extends Tokenizer_1.Tokenizer {
24
- constructor(environmentKey, containerId, styles, mode = 'credit_card', bankCountry = 'US', enableTestMode = false, layout = 'single-line', responsiveBreakpoint = tokenizer_constants_1.RESPONSIVE_BREAKPOINT) {
24
+ constructor(environmentKey, containerId, styles, mode = 'credit_card', bankCountry = 'US', enableTestMode = false, layout = 'single-line', responsiveBreakpoint = tokenizer_constants_1.RESPONSIVE_BREAKPOINT, customPlaceholders) {
25
25
  super();
26
26
  this.environmentKey = environmentKey;
27
27
  this.containerId = containerId;
28
28
  this.layout = layout;
29
+ this.customPlaceholders = customPlaceholders;
29
30
  this.bankCountry = 'US';
30
31
  this.enableTestMode = false;
31
32
  this.effectiveLayout = 'single-line';
@@ -80,7 +81,7 @@ class SpreedlyTokenizer extends Tokenizer_1.Tokenizer {
80
81
  if (!environmentKey) {
81
82
  throw new Error('Spreedly environment key is required. Provide it via gateway.config.environmentKey or client config.');
82
83
  }
83
- const tokenizer = new SpreedlyTokenizer(environmentKey, container.containerId, container.styling, container.mode || 'credit_card', container.bankCountry || 'US', container.enableTestMode || false, container.layout || 'single-line', (_b = container.responsiveBreakpoint) !== null && _b !== void 0 ? _b : tokenizer_constants_1.RESPONSIVE_BREAKPOINT);
84
+ const tokenizer = new SpreedlyTokenizer(environmentKey, container.containerId, container.styling, container.mode || 'credit_card', container.bankCountry || 'US', container.enableTestMode || false, container.layout || 'single-line', (_b = container.responsiveBreakpoint) !== null && _b !== void 0 ? _b : tokenizer_constants_1.RESPONSIVE_BREAKPOINT, container.placeholders);
84
85
  tokenizer.organizationId = config.organizationId;
85
86
  tokenizer.embedId = config.embedId;
86
87
  tokenizer.clientConfig = config.clientConfig;
@@ -139,11 +140,12 @@ class SpreedlyTokenizer extends Tokenizer_1.Tokenizer {
139
140
  reject(new Error('Spreedly initialization timeout'));
140
141
  }, tokenizer_constants_1.INIT_TIMEOUT);
141
142
  this.spreedly.on('ready', () => {
143
+ var _a, _b;
142
144
  clearTimeout(timeout);
143
- this.spreedly.setPlaceholder('number', tokenizer_constants_1.PLACEHOLDERS.cardNumber);
145
+ this.spreedly.setPlaceholder('number', ((_a = this.customPlaceholders) === null || _a === void 0 ? void 0 : _a.cardNumber) || tokenizer_constants_1.PLACEHOLDERS.cardNumber);
144
146
  this.spreedly.setFieldType('number', 'text');
145
147
  this.spreedly.setNumberFormat('prettyFormat');
146
- this.spreedly.setPlaceholder('cvv', tokenizer_constants_1.PLACEHOLDERS.cvv);
148
+ this.spreedly.setPlaceholder('cvv', ((_b = this.customPlaceholders) === null || _b === void 0 ? void 0 : _b.cvv) || tokenizer_constants_1.PLACEHOLDERS.cvv);
147
149
  this.spreedly.setFieldType('cvv', 'text');
148
150
  this.applyUnifiedStyles();
149
151
  if (this.enableTestMode &&
@@ -259,7 +261,7 @@ class SpreedlyTokenizer extends Tokenizer_1.Tokenizer {
259
261
  minWidth: tokenizer_constants_1.CANADIAN_BANK_FIELD_FLEX.accountType.minWidth,
260
262
  });
261
263
  this.applyInputStyles(this.accountTypeEl, this.mergedStyles, 'left');
262
- container.appendChild(this.accountTypeEl);
264
+ this.appendField(container, this.accountTypeEl, 'Account Type');
263
265
  this.institutionNumberEl = (0, tokenizer_utils_1.createInputElement)(`${this.containerId}-institution`, 'text', 'Inst *', 3);
264
266
  Object.assign(this.institutionNumberEl.style, {
265
267
  flex: '1',
@@ -276,7 +278,7 @@ class SpreedlyTokenizer extends Tokenizer_1.Tokenizer {
276
278
  }
277
279
  this.updateBankAccountValidation();
278
280
  });
279
- container.appendChild(this.institutionNumberEl);
281
+ this.appendField(container, this.institutionNumberEl, 'Institution');
280
282
  this.transitNumberEl = (0, tokenizer_utils_1.createInputElement)(`${this.containerId}-transit`, 'text', 'Transit *', 5);
281
283
  Object.assign(this.transitNumberEl.style, {
282
284
  flex: '2',
@@ -293,7 +295,7 @@ class SpreedlyTokenizer extends Tokenizer_1.Tokenizer {
293
295
  }
294
296
  this.updateBankAccountValidation();
295
297
  });
296
- container.appendChild(this.transitNumberEl);
298
+ this.appendField(container, this.transitNumberEl, 'Transit');
297
299
  this.accountNumberEl = (0, tokenizer_utils_1.createInputElement)(`${this.containerId}-account`, 'text', 'Account Number *');
298
300
  Object.assign(this.accountNumberEl.style, {
299
301
  flex: '1',
@@ -311,7 +313,7 @@ class SpreedlyTokenizer extends Tokenizer_1.Tokenizer {
311
313
  }
312
314
  this.updateBankAccountValidation();
313
315
  });
314
- container.appendChild(this.accountNumberEl);
316
+ this.appendField(container, this.accountNumberEl, 'Account Number');
315
317
  }
316
318
  else {
317
319
  this.institutionNumberEl = (0, tokenizer_utils_1.createInputElement)(`${this.containerId}-institution`, 'text', 'Inst *', 3);
@@ -330,7 +332,7 @@ class SpreedlyTokenizer extends Tokenizer_1.Tokenizer {
330
332
  }
331
333
  this.updateBankAccountValidation();
332
334
  });
333
- container.appendChild(this.institutionNumberEl);
335
+ this.appendField(container, this.institutionNumberEl, 'Institution');
334
336
  this.transitNumberEl = (0, tokenizer_utils_1.createInputElement)(`${this.containerId}-transit`, 'text', 'Transit *', 5);
335
337
  Object.assign(this.transitNumberEl.style, {
336
338
  flex: tokenizer_constants_1.CANADIAN_BANK_FIELD_FLEX.transitNumber.flex,
@@ -347,7 +349,7 @@ class SpreedlyTokenizer extends Tokenizer_1.Tokenizer {
347
349
  }
348
350
  this.updateBankAccountValidation();
349
351
  });
350
- container.appendChild(this.transitNumberEl);
352
+ this.appendField(container, this.transitNumberEl, 'Transit');
351
353
  this.accountNumberEl = (0, tokenizer_utils_1.createInputElement)(`${this.containerId}-account`, 'text', 'Account Number *');
352
354
  Object.assign(this.accountNumberEl.style, {
353
355
  flex: tokenizer_constants_1.CANADIAN_BANK_FIELD_FLEX.accountNumber.flex,
@@ -364,14 +366,14 @@ class SpreedlyTokenizer extends Tokenizer_1.Tokenizer {
364
366
  }
365
367
  this.updateBankAccountValidation();
366
368
  });
367
- container.appendChild(this.accountNumberEl);
369
+ this.appendField(container, this.accountNumberEl, 'Account Number');
368
370
  this.accountTypeEl = (0, tokenizer_utils_1.createAccountTypeSelect)(`${this.containerId}-account-type`);
369
371
  Object.assign(this.accountTypeEl.style, {
370
372
  flex: tokenizer_constants_1.CANADIAN_BANK_FIELD_FLEX.accountType.flex,
371
373
  minWidth: tokenizer_constants_1.CANADIAN_BANK_FIELD_FLEX.accountType.minWidth,
372
374
  });
373
375
  this.applyInputStyles(this.accountTypeEl, this.mergedStyles, 'right');
374
- container.appendChild(this.accountTypeEl);
376
+ this.appendField(container, this.accountTypeEl, 'Account Type');
375
377
  }
376
378
  }
377
379
  tokenizeBankAccountInternal(bankData) {
@@ -844,7 +846,11 @@ class SpreedlyTokenizer extends Tokenizer_1.Tokenizer {
844
846
  this.createCreditCardFields(container);
845
847
  }
846
848
  }
849
+ appendField(container, field, labelText) {
850
+ container.appendChild((0, tokenizer_utils_1.wrapFieldWithLabel)(field, labelText, this.mergedStyles));
851
+ }
847
852
  createCreditCardFields(container) {
853
+ var _a, _b;
848
854
  if (this.layout === 'responsive') {
849
855
  this.effectiveLayout = this.determineLayout(container.offsetWidth);
850
856
  }
@@ -857,8 +863,8 @@ class SpreedlyTokenizer extends Tokenizer_1.Tokenizer {
857
863
  cardNumberDiv.style.height = this.mergedStyles.input.height;
858
864
  cardNumberDiv.style.flexBasis = '100%';
859
865
  this.cardNumberDiv = cardNumberDiv;
860
- container.appendChild(cardNumberDiv);
861
- this.expiryEl = (0, tokenizer_utils_1.createInputElement)(this.expiryId, 'text', tokenizer_constants_1.PLACEHOLDERS.expiry, tokenizer_constants_1.FIELD_CONSTRAINTS.expiry.maxLength);
866
+ this.appendField(container, cardNumberDiv, 'Card Number');
867
+ this.expiryEl = (0, tokenizer_utils_1.createInputElement)(this.expiryId, 'text', ((_a = this.customPlaceholders) === null || _a === void 0 ? void 0 : _a.expiry) || tokenizer_constants_1.PLACEHOLDERS.expiry, tokenizer_constants_1.FIELD_CONSTRAINTS.expiry.maxLength);
862
868
  Object.assign(this.expiryEl.style, {
863
869
  flex: '1',
864
870
  minWidth: tokenizer_constants_1.FIELD_FLEX.expiry.minWidth,
@@ -878,18 +884,18 @@ class SpreedlyTokenizer extends Tokenizer_1.Tokenizer {
878
884
  this.validateExpiry();
879
885
  this.updateOverallValidation();
880
886
  });
881
- container.appendChild(this.expiryEl);
887
+ this.appendField(container, this.expiryEl, 'Expiration');
882
888
  const cvvDiv = (0, tokenizer_utils_1.createFieldContainer)(this.cvvEl, '1', tokenizer_constants_1.FIELD_FLEX.cvv.minWidth);
883
889
  cvvDiv.style.height = this.mergedStyles.input.height;
884
890
  this.cvvDiv = cvvDiv;
885
- container.appendChild(cvvDiv);
891
+ this.appendField(container, cvvDiv, 'CVV');
886
892
  }
887
893
  else {
888
894
  const cardNumberDiv = (0, tokenizer_utils_1.createFieldContainer)(this.numberEl, tokenizer_constants_1.FIELD_FLEX.cardNumber.flex, tokenizer_constants_1.FIELD_FLEX.cardNumber.minWidth);
889
895
  cardNumberDiv.style.height = this.mergedStyles.input.height;
890
896
  this.cardNumberDiv = cardNumberDiv;
891
- container.appendChild(cardNumberDiv);
892
- this.expiryEl = (0, tokenizer_utils_1.createInputElement)(this.expiryId, 'text', tokenizer_constants_1.PLACEHOLDERS.expiry, tokenizer_constants_1.FIELD_CONSTRAINTS.expiry.maxLength);
897
+ this.appendField(container, cardNumberDiv, 'Card Number');
898
+ this.expiryEl = (0, tokenizer_utils_1.createInputElement)(this.expiryId, 'text', ((_b = this.customPlaceholders) === null || _b === void 0 ? void 0 : _b.expiry) || tokenizer_constants_1.PLACEHOLDERS.expiry, tokenizer_constants_1.FIELD_CONSTRAINTS.expiry.maxLength);
893
899
  Object.assign(this.expiryEl.style, {
894
900
  flex: tokenizer_constants_1.FIELD_FLEX.expiry.flex,
895
901
  minWidth: tokenizer_constants_1.FIELD_FLEX.expiry.minWidth,
@@ -909,11 +915,11 @@ class SpreedlyTokenizer extends Tokenizer_1.Tokenizer {
909
915
  this.validateExpiry();
910
916
  this.updateOverallValidation();
911
917
  });
912
- container.appendChild(this.expiryEl);
918
+ this.appendField(container, this.expiryEl, 'Expiration');
913
919
  const cvvDiv = (0, tokenizer_utils_1.createFieldContainer)(this.cvvEl, tokenizer_constants_1.FIELD_FLEX.cvv.flex, tokenizer_constants_1.FIELD_FLEX.cvv.minWidth);
914
920
  cvvDiv.style.height = this.mergedStyles.input.height;
915
921
  this.cvvDiv = cvvDiv;
916
- container.appendChild(cvvDiv);
922
+ this.appendField(container, cvvDiv, 'CVV');
917
923
  if (this.layout === 'responsive') {
918
924
  this.applyLayoutStyles(this.effectiveLayout);
919
925
  this.setupResizeObserver();
@@ -929,6 +935,7 @@ class SpreedlyTokenizer extends Tokenizer_1.Tokenizer {
929
935
  }
930
936
  }
931
937
  createUSBankAccountFields(container) {
938
+ var _a, _b, _c, _d;
932
939
  if (this.layout === 'two-line') {
933
940
  this.accountTypeEl = (0, tokenizer_utils_1.createAccountTypeSelect)(`${this.containerId}-account-type`);
934
941
  Object.assign(this.accountTypeEl.style, {
@@ -936,8 +943,8 @@ class SpreedlyTokenizer extends Tokenizer_1.Tokenizer {
936
943
  minWidth: tokenizer_constants_1.BANK_FIELD_FLEX.accountType.minWidth,
937
944
  });
938
945
  this.applyInputStyles(this.accountTypeEl, this.mergedStyles, 'left');
939
- container.appendChild(this.accountTypeEl);
940
- this.routingNumberEl = (0, tokenizer_utils_1.createInputElement)(`${this.containerId}-routing`, 'text', 'Routing *', 9);
946
+ this.appendField(container, this.accountTypeEl, 'Account Type');
947
+ this.routingNumberEl = (0, tokenizer_utils_1.createInputElement)(`${this.containerId}-routing`, 'text', ((_a = this.customPlaceholders) === null || _a === void 0 ? void 0 : _a.routingNumber) || 'Routing *', 9);
941
948
  Object.assign(this.routingNumberEl.style, {
942
949
  flex: '1',
943
950
  minWidth: tokenizer_constants_1.BANK_FIELD_FLEX.routingNumber.minWidth,
@@ -953,8 +960,8 @@ class SpreedlyTokenizer extends Tokenizer_1.Tokenizer {
953
960
  }
954
961
  this.updateBankAccountValidation();
955
962
  });
956
- container.appendChild(this.routingNumberEl);
957
- this.accountNumberEl = (0, tokenizer_utils_1.createInputElement)(`${this.containerId}-account`, 'text', 'Account Number *', 17);
963
+ this.appendField(container, this.routingNumberEl, 'Routing Number');
964
+ this.accountNumberEl = (0, tokenizer_utils_1.createInputElement)(`${this.containerId}-account`, 'text', ((_b = this.customPlaceholders) === null || _b === void 0 ? void 0 : _b.accountNumber) || 'Account Number *', 17);
958
965
  Object.assign(this.accountNumberEl.style, {
959
966
  flex: '1',
960
967
  flexBasis: '100%',
@@ -971,10 +978,10 @@ class SpreedlyTokenizer extends Tokenizer_1.Tokenizer {
971
978
  }
972
979
  this.updateBankAccountValidation();
973
980
  });
974
- container.appendChild(this.accountNumberEl);
981
+ this.appendField(container, this.accountNumberEl, 'Account Number');
975
982
  }
976
983
  else {
977
- this.routingNumberEl = (0, tokenizer_utils_1.createInputElement)(`${this.containerId}-routing`, 'text', 'Routing *', 9);
984
+ this.routingNumberEl = (0, tokenizer_utils_1.createInputElement)(`${this.containerId}-routing`, 'text', ((_c = this.customPlaceholders) === null || _c === void 0 ? void 0 : _c.routingNumber) || 'Routing *', 9);
978
985
  Object.assign(this.routingNumberEl.style, {
979
986
  flex: tokenizer_constants_1.BANK_FIELD_FLEX.routingNumber.flex,
980
987
  minWidth: tokenizer_constants_1.BANK_FIELD_FLEX.routingNumber.minWidth,
@@ -990,8 +997,8 @@ class SpreedlyTokenizer extends Tokenizer_1.Tokenizer {
990
997
  }
991
998
  this.updateBankAccountValidation();
992
999
  });
993
- container.appendChild(this.routingNumberEl);
994
- this.accountNumberEl = (0, tokenizer_utils_1.createInputElement)(`${this.containerId}-account`, 'text', 'Account Number *', 17);
1000
+ this.appendField(container, this.routingNumberEl, 'Routing Number');
1001
+ this.accountNumberEl = (0, tokenizer_utils_1.createInputElement)(`${this.containerId}-account`, 'text', ((_d = this.customPlaceholders) === null || _d === void 0 ? void 0 : _d.accountNumber) || 'Account Number *', 17);
995
1002
  Object.assign(this.accountNumberEl.style, {
996
1003
  flex: tokenizer_constants_1.BANK_FIELD_FLEX.accountNumber.flex,
997
1004
  minWidth: tokenizer_constants_1.BANK_FIELD_FLEX.accountNumber.minWidth,
@@ -1007,14 +1014,14 @@ class SpreedlyTokenizer extends Tokenizer_1.Tokenizer {
1007
1014
  }
1008
1015
  this.updateBankAccountValidation();
1009
1016
  });
1010
- container.appendChild(this.accountNumberEl);
1017
+ this.appendField(container, this.accountNumberEl, 'Account Number');
1011
1018
  this.accountTypeEl = (0, tokenizer_utils_1.createAccountTypeSelect)(`${this.containerId}-account-type`);
1012
1019
  Object.assign(this.accountTypeEl.style, {
1013
1020
  flex: tokenizer_constants_1.BANK_FIELD_FLEX.accountType.flex,
1014
1021
  minWidth: tokenizer_constants_1.BANK_FIELD_FLEX.accountType.minWidth,
1015
1022
  });
1016
1023
  this.applyInputStyles(this.accountTypeEl, this.mergedStyles, 'right');
1017
- container.appendChild(this.accountTypeEl);
1024
+ this.appendField(container, this.accountTypeEl, 'Account Type');
1018
1025
  }
1019
1026
  }
1020
1027
  updateBankAccountValidation() {
@@ -37,17 +37,30 @@ exports.DEFAULT_UNIFIED_STYLES = {
37
37
  fontSize: '',
38
38
  textAlign: '',
39
39
  },
40
+ label: {
41
+ show: false,
42
+ fontSize: '0.875rem',
43
+ fontWeight: 'bold',
44
+ fontFamily: '',
45
+ color: '#333',
46
+ marginBottom: '0.25rem',
47
+ },
40
48
  };
41
49
  function mergeStyles(defaults, userStyles) {
42
50
  if (!userStyles)
43
51
  return defaults;
44
- return {
52
+ const merged = {
45
53
  input: Object.assign(Object.assign({}, defaults.input), userStyles.input),
46
54
  focus: Object.assign(Object.assign({}, defaults.focus), userStyles.focus),
47
55
  error: Object.assign(Object.assign({}, defaults.error), userStyles.error),
48
56
  container: Object.assign(Object.assign({}, defaults.container), userStyles.container),
49
57
  twoLine: Object.assign(Object.assign({}, defaults.twoLine), userStyles.twoLine),
58
+ label: Object.assign(Object.assign({}, defaults.label), userStyles.label),
50
59
  };
60
+ if (!merged.label.fontFamily) {
61
+ merged.label.fontFamily = merged.input.fontFamily;
62
+ }
63
+ return merged;
51
64
  }
52
65
  function getContainerStylesForLayout(baseStyles, layout = 'single-line') {
53
66
  if (layout === 'two-line') {
@@ -7,6 +7,8 @@ export declare function formatExpiryInput(value: string): string;
7
7
  export declare function withTimeout<T>(promise: Promise<T>, timeoutMs: number, errorMessage: string): Promise<T>;
8
8
  export declare function getConnectedBorderRadius(baseRadius: string, position: 'left' | 'middle' | 'right', isConnected: boolean): string;
9
9
  export declare function addFocusHandlers(element: HTMLElement, styles: TokenizerStylingComplete, position?: 'left' | 'middle' | 'right', onFocus?: () => void, onBlur?: () => void): void;
10
+ export declare function createFieldLabel(text: string, forId: string, styles: TokenizerStylingComplete): HTMLLabelElement;
11
+ export declare function wrapFieldWithLabel(field: HTMLElement, labelText: string, styles: TokenizerStylingComplete): HTMLElement;
10
12
  export declare function createFieldContainer(id: string, flex: string, minWidth?: string, maxWidth?: string): HTMLDivElement;
11
13
  export declare function createInputElement(id: string, type: string, placeholder: string, maxLength?: number): HTMLInputElement;
12
14
  export declare function validateRoutingNumber(routingNumber: string): boolean;
@@ -17,3 +19,4 @@ export declare function validateInstitutionNumber(institutionNumber: string): bo
17
19
  export declare function validateTransitNumber(transitNumber: string): boolean;
18
20
  export declare function validateCanadianAccountNumber(accountNumber: string): boolean;
19
21
  export declare function formatCanadianRoutingNumber(institutionNumber: string, transitNumber: string): string;
22
+ export declare function cssLengthToPixels(value: string): number;
@@ -5,6 +5,8 @@ exports.formatExpiryInput = formatExpiryInput;
5
5
  exports.withTimeout = withTimeout;
6
6
  exports.getConnectedBorderRadius = getConnectedBorderRadius;
7
7
  exports.addFocusHandlers = addFocusHandlers;
8
+ exports.createFieldLabel = createFieldLabel;
9
+ exports.wrapFieldWithLabel = wrapFieldWithLabel;
8
10
  exports.createFieldContainer = createFieldContainer;
9
11
  exports.createInputElement = createInputElement;
10
12
  exports.validateRoutingNumber = validateRoutingNumber;
@@ -15,6 +17,7 @@ exports.validateInstitutionNumber = validateInstitutionNumber;
15
17
  exports.validateTransitNumber = validateTransitNumber;
16
18
  exports.validateCanadianAccountNumber = validateCanadianAccountNumber;
17
19
  exports.formatCanadianRoutingNumber = formatCanadianRoutingNumber;
20
+ exports.cssLengthToPixels = cssLengthToPixels;
18
21
  function parseExpiryDate(value) {
19
22
  const parts = value.split('/');
20
23
  if (parts.length !== 2)
@@ -91,6 +94,43 @@ function addFocusHandlers(element, styles, position, onFocus, onBlur) {
91
94
  onBlur === null || onBlur === void 0 ? void 0 : onBlur();
92
95
  });
93
96
  }
97
+ function createFieldLabel(text, forId, styles) {
98
+ const label = document.createElement('label');
99
+ label.htmlFor = forId;
100
+ label.textContent = text;
101
+ label.style.display = styles.label.show ? 'block' : 'none';
102
+ label.style.fontSize = styles.label.fontSize;
103
+ label.style.fontWeight = styles.label.fontWeight;
104
+ label.style.fontFamily = styles.label.fontFamily;
105
+ label.style.color = styles.label.color;
106
+ label.style.marginBottom = styles.label.marginBottom;
107
+ return label;
108
+ }
109
+ function wrapFieldWithLabel(field, labelText, styles) {
110
+ if (!styles.label.show)
111
+ return field;
112
+ const wrapper = document.createElement('div');
113
+ wrapper.style.display = 'flex';
114
+ wrapper.style.flexDirection = 'column';
115
+ if (field.style.flex) {
116
+ wrapper.style.flex = field.style.flex;
117
+ field.style.flex = '';
118
+ }
119
+ if (field.style.minWidth) {
120
+ wrapper.style.minWidth = field.style.minWidth;
121
+ }
122
+ if (field.style.maxWidth) {
123
+ wrapper.style.maxWidth = field.style.maxWidth;
124
+ }
125
+ if (field.style.flexBasis) {
126
+ wrapper.style.flexBasis = field.style.flexBasis;
127
+ field.style.flexBasis = '';
128
+ }
129
+ const label = createFieldLabel(labelText, field.id, styles);
130
+ wrapper.appendChild(label);
131
+ wrapper.appendChild(field);
132
+ return wrapper;
133
+ }
94
134
  function createFieldContainer(id, flex, minWidth, maxWidth) {
95
135
  const div = document.createElement('div');
96
136
  div.id = id;
@@ -175,3 +215,19 @@ function formatCanadianRoutingNumber(institutionNumber, transitNumber) {
175
215
  const transit = transitNumber.replace(/\D/g, '').padStart(5, '0');
176
216
  return '0' + institution + transit;
177
217
  }
218
+ function cssLengthToPixels(value) {
219
+ const num = parseFloat(value);
220
+ if (isNaN(num)) {
221
+ console.warn(`[cssLengthToPixels] Cannot parse "${value}", defaulting to 14px`);
222
+ return 14;
223
+ }
224
+ if (value.endsWith('rem'))
225
+ return num * 16;
226
+ if (value.endsWith('pt'))
227
+ return num * 1.333;
228
+ if (value.endsWith('px') || !value.match(/[a-z%]/i))
229
+ return num;
230
+ console.warn(`[cssLengthToPixels] Unsupported unit in "${value}". ` +
231
+ `Only px, rem, and pt are supported. Using ${num}px as approximation.`);
232
+ return num;
233
+ }
@@ -21,6 +21,15 @@ export interface TokenizerContainer {
21
21
  enableTestMode?: boolean;
22
22
  layout?: 'single-line' | 'two-line' | 'responsive';
23
23
  responsiveBreakpoint?: number;
24
+ placeholders?: {
25
+ cardNumber?: string;
26
+ expiry?: string;
27
+ expiryMonth?: string;
28
+ expiryYear?: string;
29
+ cvv?: string;
30
+ routingNumber?: string;
31
+ accountNumber?: string;
32
+ };
24
33
  }
25
34
  export interface TokenizerStylingComplete {
26
35
  input: {
@@ -59,6 +68,14 @@ export interface TokenizerStylingComplete {
59
68
  fontSize: string;
60
69
  textAlign: string;
61
70
  };
71
+ label: {
72
+ show: boolean;
73
+ fontSize: string;
74
+ fontWeight: string;
75
+ fontFamily: string;
76
+ color: string;
77
+ marginBottom: string;
78
+ };
62
79
  }
63
80
  type DeepPartial<T> = T extends object ? {
64
81
  [P in keyof T]?: DeepPartial<T[P]>;
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@idonatedev/idonate-sdk",
3
3
  "author": "iDonate",
4
- "version": "1.2.0-dev18",
4
+ "version": "1.2.0-dev19",
5
5
  "sideEffects": false,
6
6
  "description": "iDonate Web SDK",
7
7
  "engines": {