fleetcor-lwc 3.7.0 → 3.8.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.
@@ -1,251 +1,155 @@
1
- import InputText from 'flt/inputText'
2
1
  import { api } from 'lwc'
3
2
  import { COUNTRIES } from './utils'
4
3
  import LIB_PHONE_NUMBER from 'google-libphonenumber'
5
- import IMask from 'imask'
6
- import closeButton from './close-button.svg'
7
-
4
+ import { UserDataValidator } from 'fleetcor-lwc'
8
5
  import './inputPhone.scss'
9
6
 
10
- export default class InputPhone extends InputText {
11
- flagActive
12
- mask
13
- input
14
- closeButton = closeButton
15
-
16
- required = true
17
- @api selectedCode
18
- @api picklistInsideModalView
19
-
20
- @api isValid() {
21
- let result = true
7
+ const CODE_BY_DEFAULT = 'GB'
8
+ const CODE_VALUE_SB = '+44'
22
9
 
23
- if (!this.val) {
24
- result = false
25
- }
10
+ export default class InputPhone extends UserDataValidator {
11
+ @api errorMessage
12
+ @api placeholder
13
+ @api disabled
14
+ @api required
15
+ @api codeByDefault = CODE_BY_DEFAULT
16
+ @api showDropdownAsModal
17
+ @api modalDimentionStart = 1280
26
18
 
27
- try {
28
- let phoneNumberUtil = new LIB_PHONE_NUMBER.PhoneNumberUtil()
29
- let number = phoneNumberUtil.parseAndKeepRawInput(this.formattedNumber)
30
- let regionCode = phoneNumberUtil.getRegionCodeForNumber(number)
31
- result = phoneNumberUtil.isValidNumberForRegion(number, regionCode)
32
- } catch (error) {
33
- result = false
19
+ @api
20
+ get value() {
21
+ let result = `${this.codeValue} ${this.phoneNumber}`
22
+ if (result) {
23
+ try {
24
+ let phoneNumberUtil = new LIB_PHONE_NUMBER.PhoneNumberUtil()
25
+ let number = phoneNumberUtil.parseAndKeepRawInput(result)
26
+ result = `+${number.getCountryCode()} ${number.getNationalNumber()}`
27
+ } catch (error) {}
34
28
  }
35
-
36
29
  return result
37
30
  }
38
31
 
39
- get valid(){
40
- let result = true
41
-
42
- if (!this.val) {
43
- result = false
44
- }
45
-
32
+ set value(value = '') {
46
33
  try {
47
34
  let phoneNumberUtil = new LIB_PHONE_NUMBER.PhoneNumberUtil()
48
- let number = phoneNumberUtil.parseAndKeepRawInput(this.formattedNumber)
49
- let regionCode = phoneNumberUtil.getRegionCodeForNumber(number)
50
- result = phoneNumberUtil.isValidNumberForRegion(number, regionCode)
35
+ let number = phoneNumberUtil.parseAndKeepRawInput(value)
36
+ this.codeValue = `+${number.getCountryCode()}`
37
+ this.phoneNumber = number.getNationalNumber()
51
38
  } catch (error) {
52
- result = false
39
+ this.phoneNumber = ''
53
40
  }
54
-
55
- return result
56
41
  }
57
42
 
58
43
  @api getData(silent) {
59
44
  return {
60
45
  ...super.getData(silent),
61
- value: `${this.selectedCode} ${this.val}`,
62
- separateValue: {
63
- code: this.selectedCode,
64
- phone: this.val
65
- }
46
+ codeValue: this.codeValue,
47
+ phoneNumber: this.phoneNumber,
48
+ codeByDefault: this.codeByDefault
66
49
  }
67
50
  }
68
51
 
69
- @api
70
- get value() {
71
- let result = this.formattedNumber
72
- if (result) {
73
- try {
74
- let phoneNumberUtil = new LIB_PHONE_NUMBER.PhoneNumberUtil()
75
- let number = phoneNumberUtil.parseAndKeepRawInput(result)
76
- result = `+${number.getCountryCode()} ${number.getNationalNumber()}`
77
- } catch (error) {}
78
- }
79
- return result
52
+ @api validate() {
53
+ if (this.disabled) return
54
+ this.touched = true
55
+ this.error = !this.isValid()
80
56
  }
81
57
 
82
- set value(value) {
83
- this.val = value || ''
58
+ @api isValid() {
59
+ let result = true
84
60
 
85
- if (this.val) {
86
- this.touched = true
61
+ if (this.required) {
62
+ if (!this.phoneNumber || !this.codeValue) {
63
+ result = false
64
+ }
87
65
  try {
88
66
  let phoneNumberUtil = new LIB_PHONE_NUMBER.PhoneNumberUtil()
89
- let number = phoneNumberUtil.parseAndKeepRawInput(this.val)
90
- this.selectedCode = `+${number.getCountryCode()}`
91
- this.val = number.getNationalNumber()
67
+ let number = phoneNumberUtil.parseAndKeepRawInput(
68
+ `${this.codeValue} ${this.phoneNumber}`
69
+ )
70
+ let regionCode = phoneNumberUtil.getRegionCodeForNumber(number)
71
+ result = phoneNumberUtil.isValidNumberForRegion(number, regionCode)
92
72
  } catch (error) {
93
- this.val = this.val.replace(`${this.selectedCode} `, '')
73
+ result = false
94
74
  }
95
75
  }
96
- }
97
76
 
98
- get formattedNumber() {
99
- if (this.selectedCode && this.val) {
100
- return `${this.selectedCode} ${this.val}`
101
- }
102
- }
103
-
104
- get flagOptions() {
105
- return COUNTRIES.map((item) => {
106
- return {
107
- icon: item.flag,
108
- key: item.code,
109
- value: item.dialCode,
110
- label: item.dialCode,
111
- selected: this.selectedCode == item.dialCode
112
- }
113
- })
77
+ return result
114
78
  }
115
79
 
116
- get selectedFlagOption() {
117
- return this.flagOptions.find((item) => item.value == this.selectedCode)
118
- }
80
+ phoneNumber = ''
81
+ codeValue = ''
82
+ touched
83
+ focused
119
84
 
120
- get selectedFlag() {
121
- if (this.selectedFlagOption) {
122
- return this.selectedFlagOption.icon
123
- }
85
+ get prefix() {
86
+ return this.codeValue === CODE_VALUE_SB ? CODE_VALUE_SB + '(0)' : this.codeValue
124
87
  }
125
88
 
126
- get selectedDialCode() {
127
- if (this.selectedFlagOption) {
128
- return this.selectedFlagOption.value
129
- }
89
+ handleFocus() {
90
+ this.focused = true
91
+ this.touched = true
130
92
  }
131
93
 
132
- get dialCodes() {
133
- return this.flagOptions.map((n) => n.value)
94
+ handleBlur() {
95
+ this.focused = false
134
96
  }
135
97
 
136
98
  get inputStyle() {
137
99
  return this.generateClassNameList({
138
100
  'flt-input-phone': true,
139
- 'flt-input-phone_active': this.val || this.focused,
140
- 'flt-input-phone_error': this.touched && !this.valid,
141
- 'flt-input-phone_success': this.val && this.valid,
142
- 'flt-input-phone_flag_active': this.flagActive,
143
- 'flt-input-phone_flag_selected': this.selectedCode,
144
- 'flt-input-phone_picklist-inside-modal-view': this.picklistInsideModalView
101
+ 'flt-input-phone_disabled': this.disabled,
102
+ 'flt-input-phone_active': this.focused,
103
+ 'flt-input-phone_error':
104
+ !this.focused && (this.touched || this.phoneNumber) && !this.isValid(),
105
+ 'flt-input-phone_success': this.phoneNumber && this.isValid()
145
106
  })
146
107
  }
147
108
 
148
- get computedModalClass() {
149
- return this.generateClassNameList({
150
- 'flt-input-phone__modal': true,
151
- 'flt-input-phone__modal-active': this.flagActive
109
+ get flagOptions() {
110
+ return COUNTRIES.map((item) => {
111
+ return {
112
+ icon: item.flag,
113
+ key: item.code,
114
+ value: item.dialCode,
115
+ label: `<div class="flt-input-phone__item-flag">
116
+ <img src="${item.flag}" alt="${item.dialCode}" class="flt-input-phone__flag-icon">
117
+ <span class="flt-input-phone__flag-icon-label">${item.dialCode}</span>
118
+ </div>`,
119
+ selected: this.selectedCode == item.dialCode
120
+ }
152
121
  })
153
122
  }
154
123
 
155
- renderedCallback() {
156
- if (!this.connected) {
157
- this.input = this.querySelector('input')
158
- this.mask = IMask(this.input, {
159
- mask: Number,
160
- overwrite: true,
161
- lazy: false
162
- })
163
- this.mask.unmaskedValue = this.val + ''
164
- this.mask.on('accept', this.handleChange.bind(this))
165
- this.connected = true
166
- }
167
- }
168
-
169
- handleFocused(event) {
170
- super.handleFocused(event)
171
- if (!this.mask.unmaskedValue) {
172
- this.input.setSelectionRange(
173
- this.mask.unmaskedValue.length,
174
- this.mask.unmaskedValue.length
175
- )
176
- setTimeout(() => {
177
- this.input.setSelectionRange(
178
- this.mask.unmaskedValue.length,
179
- this.mask.unmaskedValue.length
180
- )
181
- }, 60)
182
- }
124
+ get codePrefixByCountryCode() {
125
+ return COUNTRIES.find((c) => c.code === this.codeByDefault)?.dialCode
183
126
  }
184
127
 
185
- disconnectedCallback() {
186
- this.connected = false
128
+ connectedCallback() {
129
+ this.codeValue = this.codeValue || this.codePrefixByCountryCode
187
130
  }
188
131
 
189
- handleFlagActivate() {
190
- this.flagActive = !this.flagActive
132
+ handleFlagChanged(event) {
133
+ this.codeValue = event.detail.value
134
+ this.handleChange()
191
135
  }
192
136
 
193
- handleLabelClick() {
194
- this.flagActive = false
137
+ handlePhoneNumberChanged(event) {
138
+ this.phoneNumber = event.detail.value
139
+ this.handleChange()
195
140
  }
196
141
 
197
- handleSelectFlag(event) {
198
- this.flagActive = false
199
- this.selectedCode = event.currentTarget.dataset.value
200
- this.mask?.updateOptions({
201
- mask: Number,
202
- overwrite: 'shift',
203
- lazy: false
204
- })
205
- }
206
-
207
- handleChange() {
208
- this.val = this.mask?.unmaskedValue
209
-
210
- if (this.val && this.val.trimStart().startsWith('+')) {
211
- if (this.val.includes(this.selectedDialCode)) {
212
- this.val = this.val.replace(this.selectedDialCode, '').trim()
213
- } else if (this.val.trimStart().includes(' ')) {
214
- let code = this.val.trimStart().split(' ')[0]
215
- if (this.dialCodes.includes(code)) {
216
- this.val = this.val.replace(code, '').trim()
217
- this.selectedCode = code
218
- }
219
- }
142
+ handleChange(event) {
143
+ if (
144
+ this.codeValue === CODE_VALUE_SB &&
145
+ this.phoneNumber[0] === '0' &&
146
+ this.phoneNumber.length > 1
147
+ ) {
148
+ this.phoneNumber = this.phoneNumber.slice(1)
220
149
  }
221
-
222
150
  this.dispatchEvent(
223
151
  new CustomEvent('change', {
224
- detail: {
225
- ...this.getData()
226
- }
227
- })
228
- )
229
- }
230
-
231
- handleInput(event) {
232
- event.stopPropagation()
233
- this.handleChange({
234
- data: event?.target?.value
235
- })
236
- }
237
-
238
- handleBlur(event) {
239
- if (this.disabled) return
240
- this.focused = false
241
- this.touched = true
242
- this.val = (event.target.value || '').trimEnd()
243
- event.target.value = this.val
244
- this.dispatchEvent(
245
- new CustomEvent('blur_happend', {
246
- detail: null,
247
- cancelable: true,
248
- bubbles: true
152
+ detail: this.getData()
249
153
  })
250
154
  )
251
155
  }
@@ -1,288 +1,106 @@
1
1
  .flt-input-phone {
2
- color: #111827;
3
- position: relative;
4
- font-weight: 400;
5
-
6
- &_active {
7
- .flt-input-phone__number {
8
- height: 20px;
9
- opacity: 1;
10
- }
11
-
12
- .flt-input-phone__input,
13
- .flt-input-phone__code {
14
- line-height: 20px;
15
- font-size: 16px;
16
- }
17
-
18
- .flt-input-phone__placeholder {
19
- font-size: 12px;
20
- line-height: 16px;
21
- }
22
-
23
- .flt-input-phone__block {
24
- border-color: var(--input-border-color-active, #6b7280);
25
- }
26
- }
2
+ --flt-picklist-view-border-color-selected: #6b7280;
3
+ --flt-input-border-color-success: #6b7280;
27
4
 
28
5
  &_error {
29
- .flt-input-phone__block {
30
- border-color: #ef4444;
31
- }
32
-
33
6
  .flt-input-phone__error {
34
- height: 16px;
7
+ line-height: 1.5;
35
8
  opacity: 1;
36
9
  }
37
- }
38
-
39
- &_success {
40
- .flt-input-phone__block {
41
- border-color: #59eb9c;
10
+ .flt-picklist__wrapp,
11
+ .flt-input-text__wrapp {
12
+ border-color: var(--flt-input-phone-border-color-error, #ed123d);
42
13
  }
43
14
  }
44
15
 
45
- &_flag {
46
- &_active {
47
- .flt-input-phone__flag-block {
48
- &:after {
49
- content: '';
50
- transform: scale(-1);
51
- }
52
- }
53
-
54
- .flt-input-phone__flag-list {
55
- height: initial;
56
- opacity: 1;
57
- }
16
+ &_success {
17
+ .flt-picklist__wrapp,
18
+ .flt-input-text__wrapp {
19
+ border-color: var(--flt-input-phone-border-color-success, #59eb9c);
58
20
  }
59
21
  }
60
22
 
61
- &__wrapp {
62
- background-color: #fff;
63
- height: 100%;
64
- max-width: 75%;
65
- flex-grow: 1;
23
+ &__block {
66
24
  display: flex;
67
- flex-direction: column;
68
- justify-content: center;
69
- transition: all 0.3s;
25
+ align-items: start;
26
+ background-color: #ffffff;
27
+ position: relative;
70
28
  }
71
29
 
72
30
  &__number {
73
- height: 0;
74
- opacity: 0;
75
- line-height: 20px;
76
- font-size: 16px;
77
- transition: all 0.3s;
31
+ flex-grow: 1;
32
+ position: relative;
33
+ z-index: 2;
78
34
  }
79
35
 
80
- &__placeholder {
81
- font-size: 16px;
82
- line-height: 20px;
36
+ &__code {
37
+ flex-shrink: 0;
38
+ position: relative;
39
+ z-index: 1;
40
+ width: 72px;
83
41
  }
84
42
 
85
43
  &__error {
86
- height: 0;
87
44
  opacity: 0;
88
45
  font-size: 12px;
89
- line-height: 16px;
90
- color: #ef4444;
46
+ line-height: 0;
47
+ color: var(--flt-input-phone-border-color-error, #ed123d);
91
48
  transition: all 0.3s;
92
- margin-top: 4px;
93
49
  }
94
50
 
95
- &__block {
96
- padding-left: 16px;
97
- padding-right: 16px;
98
- border: 1px solid #6b7280;
99
- border-radius: var(--input-border-radius, 12px);
100
- background-color: #fff;
101
- display: flex;
102
- align-items: center;
103
- height: 44px;
104
- position: relative;
105
- z-index: 101;
51
+ .flt-input-text__wrapp {
52
+ border-bottom-left-radius: 0;
53
+ border-top-left-radius: 0;
54
+ border-left: 0;
106
55
  }
107
56
 
108
- &__flag-block {
109
- margin-right: 8px;
110
- display: flex;
111
- align-items: center;
112
- justify-content: space-between;
113
- font-size: 16px;
114
- width: 56px;
115
- line-height: 20px;
116
-
117
- &:after {
118
- content: '';
119
- display: inline-block;
120
- transition: all 0.3s;
121
- width: 24px;
122
- height: 24px;
123
- background: url('./arrow.svg') no-repeat;
124
- background-size: contain;
125
- }
57
+ .flt-picklist__wrapp {
58
+ border-bottom-right-radius: 0;
59
+ border-top-right-radius: 0;
60
+ border-right: 0;
61
+ padding-right: 0;
126
62
  }
127
63
 
128
- &__flag-wrapper {
129
- position: relative;
130
- flex-shrink: 0;
64
+ .flt-picklist__dropdown-container,
65
+ .flt-input-phone__code,
66
+ .flt-picklist_active {
67
+ position: initial;
131
68
  }
132
69
 
133
- &__flag-list {
134
- height: 0;
135
- opacity: 0;
136
- padding: 0;
137
- margin: 0;
138
- list-style-type: none;
139
- position: absolute;
140
- z-index: 100;
141
- background-color: #fff;
142
- border-bottom-right-radius: 12px;
143
- border-bottom-left-radius: 12px;
144
- box-shadow: 0px 10px 15px -3px rgba(16, 24, 40, 0.1);
145
- left: 0;
146
- top: 22px;
147
- width: 100%;
148
- overflow: hidden;
149
- transition: all 0.3s;
150
- max-height: 212px;
151
- overflow-y: scroll;
70
+ .flt-picklist__dropdown {
71
+ top: 32px;
152
72
  }
153
73
 
154
- &__flag-list-item {
155
- padding: 12px 17px;
156
- display: flex;
157
- align-items: center;
158
- border-bottom: 1px solid #eeeeee;
159
- background-color: #fff;
160
-
161
- &:first-child {
162
- padding-top: 30px;
163
- }
164
-
165
- &:last-child {
166
- border-bottom: none;
167
- border-bottom-right-radius: 12px;
168
- border-bottom-left-radius: 12px;
169
- }
170
-
171
- &_selected {
172
- background-color: var(--flag-list-item-selected-bg-color, #f2d400);
74
+ .flt-modal {
75
+ .flt-picklist__dropdown {
76
+ top: initial;
173
77
  }
174
78
  }
79
+ .flt-picklist__placeholder {
80
+ display: none;
81
+ }
175
82
 
176
- &__flag-icon-label {
177
- margin-left: 1rem;
83
+ &__item-flag {
84
+ display: flex;
85
+ align-items: center;
86
+ gap: 16px;
178
87
  }
179
88
 
180
- &__flag-icon,
181
- &__flag-selected-icon {
89
+ &__flag-icon {
182
90
  width: 24px;
183
91
  height: 24px;
184
92
  border-radius: 100%;
185
93
  object-fit: cover;
186
94
  }
187
95
 
188
- &__flag-selected-value {
189
- display: flex;
190
- }
191
-
192
- &__number {
193
- display: flex;
194
- }
195
-
196
- &__input {
197
- width: 100%;
198
- line-height: 0;
199
- font-size: 0;
200
- transition: all 0.3s;
201
- outline: none;
202
- border: none;
203
- padding: 0;
204
- letter-spacing: 1px;
205
- }
206
-
207
- &__code {
208
- line-height: 0;
209
- font-size: 0;
210
- transition: all 0.3s;
211
- margin-right: 8px;
212
- }
213
-
214
- &_picklist-inside-modal-view {
215
- .flt-input-phone__modal-active {
216
- position: initial;
217
- display: initial;
218
- }
219
-
220
- .flt-input-phone__modal-glass,
221
- .flt-input-phone__modal-header {
96
+ .flt-picklist__value {
97
+ .flt-input-phone__flag-icon-label {
222
98
  display: none;
223
99
  }
100
+ }
224
101
 
225
- @media (max-width: 1279px) {
226
- .flt-input-phone__modal {
227
- display: none;
228
- }
229
-
230
- .flt-input-phone__modal-active {
231
- position: fixed;
232
- display: flex;
233
- align-items: center;
234
- justify-content: center;
235
- top: 0;
236
- left: 0;
237
- width: 100%;
238
- height: 100%;
239
- z-index: 200000;
240
- }
241
-
242
- .flt-input-phone__modal-glass {
243
- display: block;
244
- position: absolute;
245
- width: 100%;
246
- height: 100%;
247
- left: 0;
248
- top: 0;
249
- background: rgba(0, 0, 0, 0.4);
250
- }
251
-
252
- .flt-input-phone__modal-container {
253
- position: relative;
254
- background-color: #ffffff;
255
- border-radius: var(--input-border-radius, 12px);
256
- overflow: hidden;
257
-
258
- .flt-input-phone__flag-list {
259
- position: initial;
260
- max-width: 300px;
261
- width: 300px;
262
- top: initial;
263
- left: initial;
264
- }
265
- }
266
-
267
- .flt-input-phone__modal-header {
268
- display: flex;
269
- align-items: center;
270
- justify-content: space-between;
271
- font-weight: 600;
272
- padding: 12px;
273
- background-color: var(--gray-5, #f8f8f8);
274
- }
275
-
276
- .flt-input-phone__flag-list {
277
- max-height: 80vh !important;
278
- overflow: auto !important;
279
- }
280
-
281
- .flt-input-phone__flag-list-item {
282
- &:first-child {
283
- padding-top: 12px;
284
- }
285
- }
286
- }
102
+ [user-data-modal='true'] + .flt-input-phone__number {
103
+ position: initial;
104
+ z-index: initial;
287
105
  }
288
106
  }