fleetcor-lwc 3.6.2 → 3.7.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.
package/README.md CHANGED
@@ -338,6 +338,52 @@ Add / update `lwc.config.json` file in your project
338
338
  | ------ | ------------ | ------ | ------------------------------------- |
339
339
  | change | event.detail | object | Return full data of component's state |
340
340
 
341
+ ### Picklist Chips
342
+
343
+ ```html
344
+ <flt-picklist
345
+ name="city"
346
+ required
347
+ show-dropdown-as-modal
348
+ placeholder="City"
349
+ error-message="Error! Empty field"
350
+ required
351
+ value="London"
352
+ options="[{label:'London', value:'London'}, {label:'Leon', value:'Leon'}]"
353
+ >
354
+ </flt-picklist>
355
+ ...
356
+ ```
357
+
358
+ #### Picklist variables
359
+
360
+ | @api variables | type | values | required | description |
361
+ | ------------------- | ------ | -------- | -------- | --------------------------------------------------------------------------------------------- |
362
+ | name | string | | + | |
363
+ | options | array | | + | Array of available items with `label` and `value` as unique string |
364
+ | size | string | `medium` | - | Size of buttons (button sizes) |
365
+ | showDropdownAsModal | bool | | - | Show modal with selected options |
366
+ | modalDimentionStart | int | 1280 | - | If showDropdownAsModal is true, by default modal become visible window width less then 1280px |
367
+ | value | string | | - | Current value from options items value |
368
+ | disabled | bool | | - | |
369
+ | required | bool | | - | |
370
+ | group | string | | - | |
371
+ | error-message | string | | - | |
372
+
373
+ #### Picklist methods
374
+
375
+ | @api | params | return type | description |
376
+ | -------- | ----------- | ----------- | ----------------------------------------------------------------------------------------------------------------------- |
377
+ | validate | | void | Check component validation and show error message to user |
378
+ | isValid | | bool | Return `true` or `false` |
379
+ | getData | silent:bool | object | Return full data of component's state. If `silent` true - return value will be without any errors displaying for client |
380
+
381
+ #### Picklist events
382
+
383
+ | name | handle | return | description |
384
+ | ------ | ------------ | ------ | ------------------------------------- |
385
+ | change | event.detail | object | Return full data of component's state |
386
+
341
387
  ### Input Text
342
388
 
343
389
  ```html
@@ -486,6 +532,7 @@ You can override them as you wish by global css variables as priority.
486
532
  --flt-button-border-radius: 32px;
487
533
  --flt-button-padding: 0 24px;
488
534
  --flt-button-gap: 16px;
535
+ --flt-button-fw: 700;
489
536
  --flt-checkbox-border-color: #6b7280;
490
537
  --flt-checkbox-bg-color: #ffffff;
491
538
  --flt-checkbox-agree-color: #59eb9c;
@@ -541,11 +588,43 @@ You can override them as you wish by global css variables as priority.
541
588
  --flt-radio-group-chips-label-mb: 4px;
542
589
  --flt-radio-group-chips-error-color: #ed123d;
543
590
  --flt-radio-group-chips-error-fz: 12px;
591
+ --flt-picklist-view-border-color-selected: #59eb9c;
592
+ --flt-picklist-placeholder-activate-fz: 12px;
593
+ --flt-picklist-placeholder-activate-lh: 16px;
594
+ --flt-picklist-bgc: #ffffff;
595
+ --flt-picklist-border: 1px solid #6b7280;
596
+ --flt-picklist-border-radius: 12px;
597
+ --flt-picklist-wrapper-height: 44px;
598
+ --flt-picklist-wrapper-padding: 0 16px;
599
+ --flt-picklist-error-color: #ed123d;
600
+ --flt-picklist-error-fz: 12px;
601
+ --flt-picklist-placeholder-color: #111827;
602
+ --flt-picklist-placeholder-fz: 16px;
603
+ --flt-picklist-placeholder-lh: 20px;
604
+ --flt-picklist-view-arrow-path-stroke: #4c4c4c;
605
+ --flt-picklist-dropdown-border: none;
606
+ --flt-picklist-dropdown-bgc: #ffffff;
607
+ --flt-picklist-option-padding: 12px 16px;
608
+ --flt-picklist-option-color: #4c4c4c;
609
+ --flt-picklist-dropdown-option-border-bottom-color: #eeeeee;
610
+ --flt-picklist-option-selected-color: #4c4c4c;
611
+ --flt-picklist-dropdown-option-bgc: #f2d400;
612
+ --flt-picklist-option-first-child-padding: 32px 16px 12px;
613
+ --flt-picklist-option-padding: 12px 16px;
614
+ --flt-picklist-dropdown-modal-header-bgc: #f3f4f6;
544
615
  }
545
616
  ```
546
617
 
547
618
  ## Release Notes:
548
619
 
620
+ - v.3.7.0
621
+
622
+ - Added new component `flt-picklist`
623
+
624
+ - v.3.6.3
625
+
626
+ - Updated `flt-button` componentm styles
627
+
549
628
  - v.3.6.2
550
629
 
551
630
  - Updated `flt-radio-group-chips` componentm styles
@@ -87,7 +87,7 @@ button {
87
87
  display: flex;
88
88
  align-items: center;
89
89
  font-family: inherit;
90
- font-weight: 700;
90
+ font-weight: var(--flt-button-fw, 700);
91
91
  border-radius: $FLT_BUTTON_BORDER_RADIUS;
92
92
  box-sizing: border-box;
93
93
  padding: $FLT_BUTTON_PADDING;
@@ -0,0 +1,135 @@
1
+ import { createElement } from 'lwc'
2
+ import Picklist from 'flt/picklist'
3
+
4
+ Object.defineProperty(window, 'matchMedia', {
5
+ writable: true,
6
+ value: jest.fn().mockImplementation((query) => ({
7
+ matches: false
8
+ // media: query,
9
+ // onchange: null,
10
+ // addListener: jest.fn(), // Deprecated
11
+ // removeListener: jest.fn(), // Deprecated
12
+ // addEventListener: jest.fn(),
13
+ // removeEventListener: jest.fn(),
14
+ // dispatchEvent: jest.fn()
15
+ }))
16
+ })
17
+
18
+ describe('flt-picklist', () => {
19
+ afterEach(() => {
20
+ while (document.body.firstChild) {
21
+ document.body.removeChild(document.body.firstChild)
22
+ }
23
+ })
24
+
25
+ it('base test', async () => {
26
+ const picklistEl = createElement('flt-picklist', { is: Picklist })
27
+ picklistEl.errorMessage = 'Error message'
28
+ picklistEl.required = true
29
+ picklistEl.options = [
30
+ {
31
+ label: 'Man',
32
+ value: 'man'
33
+ },
34
+ {
35
+ label: 'Woman',
36
+ value: 'woman'
37
+ }
38
+ ]
39
+ picklistEl.name = 'sex'
40
+ document.body.appendChild(picklistEl)
41
+ await expect(picklistEl.firstChild.classList).toContain('flt-picklist')
42
+ picklistEl.firstChild.focus()
43
+
44
+ return Promise.resolve().then(async () => {
45
+ const dropDownEl = picklistEl.querySelector('.flt-picklist__dropdown')
46
+ await expect(dropDownEl).toBeTruthy()
47
+ dropDownEl.querySelector('.flt-picklist__option').click()
48
+
49
+ return Promise.resolve().then(async () => {
50
+ const data = picklistEl.getData()
51
+ await expect(data.value).toBe('man')
52
+ })
53
+ })
54
+ })
55
+
56
+ it('disabled test', async () => {
57
+ const picklistEl = createElement('flt-picklist', { is: Picklist })
58
+ picklistEl.errorMessage = 'Error message'
59
+ picklistEl.required = true
60
+ picklistEl.disabled = true
61
+ picklistEl.options = [
62
+ {
63
+ label: 'Man',
64
+ value: 'man'
65
+ },
66
+ {
67
+ label: 'Woman',
68
+ value: 'woman'
69
+ }
70
+ ]
71
+ picklistEl.name = 'sex'
72
+ document.body.appendChild(picklistEl)
73
+ await expect(picklistEl.firstChild.classList).toContain('flt-picklist')
74
+ picklistEl.firstChild.focus()
75
+
76
+ return Promise.resolve().then(async () => {
77
+ const dropDownEl = picklistEl.querySelector('.flt-picklist__dropdown')
78
+ await expect(dropDownEl).toBeFalsy()
79
+ })
80
+ })
81
+
82
+ it('modal test', async () => {
83
+ const picklistEl = createElement('flt-picklist', { is: Picklist })
84
+ picklistEl.errorMessage = 'Error message'
85
+ picklistEl.placeholder = 'Sex'
86
+ picklistEl.required = true
87
+ picklistEl.showDropdownAsModal = true
88
+ picklistEl.options = [
89
+ {
90
+ label: 'Man',
91
+ value: 'man'
92
+ },
93
+ {
94
+ label: 'Woman',
95
+ value: 'woman'
96
+ }
97
+ ]
98
+ picklistEl.name = 'sex'
99
+ document.body.appendChild(picklistEl)
100
+ await expect(picklistEl.firstChild.classList).toContain('flt-picklist')
101
+ picklistEl.firstChild.focus()
102
+
103
+ return Promise.resolve().then(async () => {
104
+ const dropDownEl = picklistEl.querySelector('.flt-picklist__dropdown')
105
+ await expect(dropDownEl).toBeTruthy()
106
+ dropDownEl.querySelector('.flt-picklist__option').click()
107
+ picklistEl.firstChild.blur()
108
+
109
+ return Promise.resolve().then(async () => {
110
+ const data = picklistEl.getData()
111
+ await expect(data.value).toBe('man')
112
+ picklistEl.firstChild.focus()
113
+ return Promise.resolve().then(async () => {
114
+ await expect(picklistEl.firstChild.classList).toContain('flt-picklist_modal')
115
+ const modalEl = document.body.querySelector('flt-modal')
116
+ await expect(modalEl).toBeTruthy()
117
+ const closeButtonEl = modalEl.querySelector(
118
+ '.flt-picklist__modal-header-close-button'
119
+ )
120
+ const clickEvent = new MouseEvent('click', {
121
+ bubbles: true,
122
+ cancelable: true,
123
+ view: window
124
+ })
125
+
126
+ closeButtonEl.dispatchEvent(clickEvent)
127
+ return Promise.resolve().then(async () => {
128
+ const modalEl = picklistEl.querySelector('flt-modal')
129
+ await expect(modalEl).toBeFalsy()
130
+ })
131
+ })
132
+ })
133
+ })
134
+ })
135
+ })
@@ -0,0 +1,47 @@
1
+ <template lwc:render-mode="light">
2
+ <div class={computedStyles} tabindex="0" onfocus={handleShowView} onblur={handleHideView}>
3
+ <div class="flt-picklist__wrapp">
4
+ <div class="flt-picklist__wrapp-text">
5
+ <div class="flt-picklist__placeholder">{placeholder}</div>
6
+ <div class="flt-picklist__value">{displayLabel}</div>
7
+ </div>
8
+ <svg
9
+ width="24"
10
+ height="24"
11
+ viewBox="0 0 24 24"
12
+ fill="none"
13
+ class="flt-picklist__view-arrow">
14
+ <path
15
+ d="M19 9L12 16L5 9"
16
+ stroke-width="2"
17
+ stroke-linecap="round"
18
+ stroke-linejoin="round"
19
+ class="flt-picklist__view-arrow-path"></path>
20
+ </svg>
21
+ </div>
22
+ <div class="flt-picklist__dropdown-container">
23
+ <div lwc:if={showOptions} class="flt-picklist__dropdown">
24
+ <template for:each={optionsToDisplay} for:item="option">
25
+ <div
26
+ lwc:if={option.selected}
27
+ key={option.value}
28
+ onclick={handleChange}
29
+ data-value={option.value}
30
+ class="flt-picklist__option flt-picklist__option_selected">
31
+ {option.label}
32
+ </div>
33
+ <div
34
+ lwc:else
35
+ onclick={handleChange}
36
+ key={option.value}
37
+ data-value={option.value}
38
+ class="flt-picklist__option">
39
+ {option.label}
40
+ </div>
41
+ </template>
42
+ </div>
43
+ </div>
44
+
45
+ <div class={computedErrorMessage}>{errorMessage}</div>
46
+ </div>
47
+ </template>
@@ -0,0 +1,98 @@
1
+ import { api } from 'lwc'
2
+ import { SelectElement } from 'fleetcor-lwc'
3
+ import './picklist.scss'
4
+ import picklistModal from './picklistModal.html'
5
+ import picklist from './picklist.html'
6
+
7
+ export default class Picklist extends SelectElement {
8
+ error
9
+ showOptions
10
+ isDesktop
11
+
12
+ @api errorMessage
13
+ @api placeholder
14
+ @api prefix
15
+ @api showDropdownAsModal
16
+ @api modalDimentionStart = 1280
17
+
18
+ render() {
19
+ let result = picklist
20
+ if (this.showDropdownAsModal && !this.isDesktop) {
21
+ result = picklistModal
22
+ }
23
+ return result
24
+ }
25
+
26
+ @api validate() {
27
+ this.error = !this.isValid()
28
+ }
29
+
30
+ get displayLabel() {
31
+ return this.optionsToDisplay.find((item) => item.selected)?.label
32
+ }
33
+
34
+ connectedCallback() {
35
+ if (this.showDropdownAsModal) {
36
+ this.handleResize()
37
+ window.addEventListener('resize', this.handleResize.bind(this))
38
+ }
39
+ }
40
+
41
+ disconnectedCallback() {
42
+ if (this.showDropdownAsModal) {
43
+ window.removeEventListener('resize', this.handleResize.bind(this))
44
+ }
45
+ }
46
+
47
+ handleResize() {
48
+ this.isDesktop = window.matchMedia(`(min-width: ${this.modalDimentionStart}px)`).matches
49
+ }
50
+
51
+ handleHideView(event) {
52
+ event.stopPropagation()
53
+ if (!this.disabled) {
54
+ this.showOptions = false
55
+ }
56
+ }
57
+
58
+ handleCloseModal() {
59
+ this.querySelector('.flt-picklist').blur()
60
+ }
61
+
62
+ handleShowView(event) {
63
+ event.stopPropagation()
64
+ if (!this.disabled) {
65
+ this.showOptions = true
66
+ }
67
+ }
68
+
69
+ handleChange(event) {
70
+ event.stopPropagation()
71
+ if (!this.disabled) {
72
+ this.value = event.target.dataset.value
73
+ this.dispatchEvent(
74
+ new CustomEvent('change', {
75
+ detail: this.getData()
76
+ })
77
+ )
78
+
79
+ this.querySelector('.flt-picklist').blur()
80
+ }
81
+ }
82
+
83
+ get computedStyles() {
84
+ return this.generateClassNameList({
85
+ 'flt-picklist': true,
86
+ 'flt-picklist_active': this.showOptions,
87
+ 'flt-picklist_selected': this.value,
88
+ 'flt-picklist_modal': this.showDropdownAsModal && this.showOptions && !this.isDesktop
89
+ })
90
+ }
91
+
92
+ get computedErrorMessage() {
93
+ return this.generateClassNameList({
94
+ 'flt-picklist__error-message': true,
95
+ 'flt-picklist__error-message_active': this.error
96
+ })
97
+ }
98
+ }
@@ -0,0 +1,172 @@
1
+ .flt-picklist {
2
+ outline: none;
3
+
4
+ &_active {
5
+ position: relative;
6
+ z-index: 10000;
7
+ .flt-picklist__view-arrow {
8
+ transform: scale(-1);
9
+ }
10
+ }
11
+
12
+ &_selected {
13
+ .flt-picklist__wrapp {
14
+ border-color: var(--flt-picklist-view-border-color-selected, #59eb9c);
15
+ }
16
+
17
+ .flt-picklist__placeholder {
18
+ font-size: var(--flt-picklist-placeholder-activate-fz, 12px);
19
+ line-height: var(--flt-picklist-placeholder-activate-lh, 16px);
20
+ }
21
+ }
22
+
23
+ &_modal {
24
+ position: initial;
25
+ z-index: initial;
26
+
27
+ .flt-picklist__wrapp {
28
+ position: initial;
29
+ z-index: initial;
30
+ }
31
+ }
32
+
33
+ &__wrapp {
34
+ background-color: var(--flt-picklist-bgc, #ffffff);
35
+ border: var(--flt-picklist-border, 1px solid #6b7280);
36
+ border-radius: var(--flt-picklist-border-radius, 12px);
37
+ overflow: hidden;
38
+ height: var(--flt-picklist-wrapper-height, 44px);
39
+ display: flex;
40
+ justify-content: space-between;
41
+ gap: 12px;
42
+ align-items: center;
43
+ padding: var(--flt-picklist-wrapper-padding, 0 16px);
44
+ transition: all 0.3s;
45
+ cursor: pointer;
46
+ position: relative;
47
+ z-index: 1;
48
+ }
49
+
50
+ &__error-message {
51
+ color: var(--flt-picklist-error-color, #ed123d);
52
+ opacity: 0;
53
+ line-height: 0;
54
+ transition: all 0.3s;
55
+ font-size: var(--flt-picklist-error-fz, 12px);
56
+
57
+ &_active {
58
+ opacity: 1;
59
+ line-height: 1.5;
60
+ }
61
+ }
62
+
63
+ &__placeholder {
64
+ transition: all 0.3s;
65
+ color: var(--flt-picklist-placeholder-color, #111827);
66
+ font-size: var(--flt-picklist-placeholder-fz, 16px);
67
+ line-height: var(--flt-picklist-placeholder-lh, 20px);
68
+ }
69
+
70
+ &__view-arrow-path {
71
+ stroke: var(--flt-picklist-view-arrow-path-stroke, #4c4c4c);
72
+ }
73
+
74
+ &__view-arrow {
75
+ transition: all 0.3s;
76
+ flex-shrink: 0;
77
+ }
78
+
79
+ &__dropdown-container {
80
+ position: relative;
81
+ }
82
+
83
+ &__dropdown {
84
+ position: absolute;
85
+ width: 100%;
86
+ top: -20px;
87
+ left: 0;
88
+ max-height: 240px;
89
+ border: var(--flt-picklist-dropdown-border, none);
90
+ overflow: auto;
91
+ background: var(--flt-picklist-dropdown-bgc, #ffffff);
92
+ box-shadow: 0px 30px 40px rgba(33, 46, 53, 0.3);
93
+ cursor: pointer;
94
+ border-bottom-left-radius: var(--flt-picklist-border-radius, 12px);
95
+ border-bottom-right-radius: var(--flt-picklist-border-radius, 12px);
96
+ animation: fadeIn 0.3s ease-in-out;
97
+ }
98
+
99
+ &__option {
100
+ display: block;
101
+ padding: var(--flt-picklist-option-padding, 12px 16px);
102
+ color: var(--flt-picklist-option-color, #4c4c4c);
103
+ user-select: none;
104
+ box-sizing: border-box;
105
+ border-bottom: 1px solid var(--flt-picklist-dropdown-option-border-bottom-color, #eeeeee);
106
+ position: relative;
107
+ line-height: 18px;
108
+
109
+ &:hover,
110
+ &_selected {
111
+ color: var(--flt-picklist-option-selected-color, #4c4c4c);
112
+ background: var(--flt-picklist-dropdown-option-bgc, #f2d400);
113
+ }
114
+
115
+ &:first-child {
116
+ padding: var(--flt-picklist-option-first-child-padding, 32px 16px 12px);
117
+ }
118
+
119
+ &:last-child {
120
+ border-bottom: none;
121
+ border-bottom-left-radius: var(--flt-picklist-border-radius, 12px);
122
+ border-bottom-right-radius: var(--flt-picklist-border-radius, 12px);
123
+ }
124
+ }
125
+
126
+ &__modal {
127
+ background-color: #fff;
128
+ overflow: hidden;
129
+ border-radius: var(--flt-picklist-border-radius, 12px);
130
+ width: 90vw;
131
+
132
+ .flt-picklist__dropdown {
133
+ position: relative;
134
+ top: initial;
135
+ left: initial;
136
+ animation: initial;
137
+ max-height: calc(100vh - 100px);
138
+ }
139
+
140
+ .flt-picklist__option {
141
+ &:first-child {
142
+ padding: var(--flt-picklist-option-padding, 12px 16px);
143
+ }
144
+ }
145
+ }
146
+
147
+ &__modal-header-close-button {
148
+ padding: 4px;
149
+ width: 16px;
150
+ height: 16px;
151
+ }
152
+
153
+ &__modal-header {
154
+ display: flex;
155
+ justify-content: space-between;
156
+ align-items: center;
157
+ font-weight: 700;
158
+ padding: 12px 16px;
159
+ background-color: var(--flt-picklist-dropdown-modal-header-bgc, #f3f4f6);
160
+ border-top-left-radius: var(--flt-picklist-border-radius, 12px);
161
+ border-top-right-radius: var(--flt-picklist-border-radius, 12px);
162
+ }
163
+ }
164
+
165
+ @keyframes fadeIn {
166
+ 0% {
167
+ opacity: 0;
168
+ }
169
+ 100% {
170
+ opacity: 100%;
171
+ }
172
+ }
@@ -0,0 +1,70 @@
1
+ <template lwc:render-mode="light">
2
+ <div class={computedStyles} tabindex="0" onfocus={handleShowView} onblur={handleHideView}>
3
+ <div class="flt-picklist__wrapp">
4
+ <div class="flt-picklist__wrapp-text">
5
+ <div class="flt-picklist__placeholder">{placeholder}</div>
6
+ <div class="flt-picklist__value">{displayLabel}</div>
7
+ </div>
8
+ <svg
9
+ width="24"
10
+ height="24"
11
+ viewBox="0 0 24 24"
12
+ fill="none"
13
+ class="flt-picklist__view-arrow">
14
+ <path
15
+ d="M19 9L12 16L5 9"
16
+ stroke-width="2"
17
+ stroke-linecap="round"
18
+ stroke-linejoin="round"
19
+ class="flt-picklist__view-arrow-path"></path>
20
+ </svg>
21
+ </div>
22
+ <div class="flt-picklist__dropdown-container">
23
+ <flt-modal lwc:if={showOptions} deactive-glass>
24
+ <div class="flt-picklist__modal">
25
+ <div class="flt-picklist__modal-header">
26
+ <div class="flt-picklist__modal-header-placeholder">{placeholder}:</div>
27
+ <svg
28
+ onclick={handleCloseModal}
29
+ class="flt-picklist__modal-header-close-button"
30
+ x="0px"
31
+ y="0px"
32
+ width="32px"
33
+ height="32px"
34
+ viewBox="0 0 612 612"
35
+ style="enable-background: new 0 0 612 612"
36
+ xml:space="preserve">
37
+ <polygon
38
+ points="612,36.004 576.521,0.603 306,270.608 35.478,0.603 0,36.004 270.522,306.011 0,575.997 35.478,611.397 306,341.411 576.521,611.397 612,575.997 341.459,306.011 "
39
+ data-original="#000000"
40
+ class="active-path"
41
+ data-old_color="#000000"
42
+ fill="#111827"></polygon>
43
+ </svg>
44
+ </div>
45
+ <div class="flt-picklist__dropdown">
46
+ <template for:each={optionsToDisplay} for:item="option">
47
+ <div
48
+ lwc:if={option.selected}
49
+ key={option.value}
50
+ onclick={handleChange}
51
+ data-value={option.value}
52
+ class="flt-picklist__option flt-picklist__option_selected">
53
+ {option.label}
54
+ </div>
55
+ <div
56
+ lwc:else
57
+ onclick={handleChange}
58
+ key={option.value}
59
+ data-value={option.value}
60
+ class="flt-picklist__option">
61
+ {option.label}
62
+ </div>
63
+ </template>
64
+ </div>
65
+ </div>
66
+ </flt-modal>
67
+ </div>
68
+ <div class={computedErrorMessage}>{errorMessage}</div>
69
+ </div>
70
+ </template>
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "fleetcor-lwc",
3
- "version": "3.6.2",
3
+ "version": "3.7.0",
4
4
  "description": "LWC framework by Fleetcor",
5
5
  "repository": {
6
6
  "type": "git",
@@ -32,6 +32,7 @@
32
32
  "flt/icon",
33
33
  "flt/inputText",
34
34
  "flt/inputEmail",
35
+ "flt/picklist",
35
36
  "flt/modal",
36
37
  "flt/radioGroup",
37
38
  "flt/radioGroupIcon",