@rypen-dev/shared-components 5.0.12 → 5.0.13

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/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@rypen-dev/shared-components",
3
3
  "description": "Shared styles and Vuejs ui components for Rypen projects.",
4
- "version": "5.0.12",
4
+ "version": "5.0.13",
5
5
  "main": "./dist/index.js",
6
6
  "scripts": {
7
7
  "build": "webpack --config ./webpack.config.js",
@@ -339,6 +339,10 @@ a.info {
339
339
  }
340
340
  }
341
341
 
342
+ &.small-text {
343
+ font-size: 0.875rem;
344
+ }
345
+
342
346
  &.secondary {
343
347
  color: $secondary;
344
348
 
@@ -485,6 +489,52 @@ a.info {
485
489
  }
486
490
  }
487
491
 
492
+ &.secondary {
493
+ color: $secondary;
494
+
495
+ &::before,
496
+ &::after {
497
+ border-color: $secondary;
498
+ }
499
+ }
500
+
501
+ &.success-alt {
502
+ color: $success-alt;
503
+
504
+ &::before,
505
+ &::after {
506
+ border-color: $success-alt;
507
+ }
508
+ }
509
+
510
+ &.tertiary {
511
+ color: $tertiary;
512
+
513
+ &::before,
514
+ &::after {
515
+ border-color: $tertiary;
516
+ }
517
+ }
518
+
519
+ @media screen and (min-width: map-get($breakpoints, meidum)) and (max-width: map-get($breakpoints, large) - 1px) {
520
+ &.medium-only-small-text {
521
+ font-size: 0.875rem;
522
+ }
523
+
524
+ &.medium-only-no-tail {
525
+ padding-right: 20px;
526
+
527
+ &::before {
528
+ display: none;
529
+ }
530
+
531
+ &.reversed {
532
+ padding-right: 0;
533
+ padding-left: 20px;
534
+ }
535
+ }
536
+ }
537
+
488
538
  @media print, screen and (min-width: map-get($breakpoints, medium)) {
489
539
  line-height: 1.125rem;
490
540
  font-size: 1.0625rem;
@@ -683,6 +683,12 @@ label {
683
683
  font-size: 1.25rem;
684
684
  }
685
685
 
686
+ &.select::after {
687
+ top: 22px;
688
+ width: 12px;
689
+ height: 12px;
690
+ }
691
+
686
692
  textarea {
687
693
  font-size: 1.25rem;
688
694
  }
@@ -863,7 +869,8 @@ label {
863
869
 
864
870
  &::after {
865
871
  content: '';
866
- background-image: url('/assets/images/search-input.svg');
872
+ //background-image: url('/assets/images/search-input.svg');
873
+ background-image: url('data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIyNCIgaGVpZ2h0PSIyNCIgdmlld0JveD0iMCAwIDI0IDI0Ij4NCiAgICA8cGF0aCBmaWxsPSIjNTA0MTc0IiBmaWxsLXJ1bGU9ImV2ZW5vZGQiIGQ9Ik0xMi41OSAxNS4zNDNhNi42MiA2LjYyIDAgMCAxLTIuOTU4LS4xMzhjLTIuNzExLS43NjctNC42MDQtMy4yMy00LjYwNC01Ljk5IDAtMy40MzcgMi44NjItNi4yMzQgNi4zOC02LjIzNCAzLjUxOSAwIDYuMzgxIDIuNzk3IDYuMzgxIDYuMjM0IDAgMy0yLjE4NiA1LjU3OC01LjIgNi4xMjhtNy4yMDggNi4yMjRsLTMuMzctNS43NmMyLjIxNC0xLjYxMSAzLjU2Mi00LjI1IDMuMzcyLTcuMTI5LS4yNzEtNC4xMjMtMy43MzMtNy40NTktNy45NTctNy42NjdDNy4wMS43NzIgMyA0LjU0NSAzIDkuMjE1YzAgMy42MzcgMi40OTUgNi44ODMgNi4wNjggNy44OTNhOC42MDkgOC42MDkgMCAwIDAgMy44OTQuMTgyIDguNTMgOC41MyAwIDAgMCAxLjcwNS0uNWwzLjM3IDUuNzZhLjYzOS42MzkgMCAwIDAgLjg2LjIzbC42NjUtLjM3MmEuNjA5LjYwOSAwIDAgMCAuMjM1LS44NCIvPg0KPC9zdmc+DQo=');
867
874
  background-size: 100%;
868
875
  display: block;
869
876
  position: absolute;
@@ -873,6 +880,20 @@ label {
873
880
  height: 24px;
874
881
  }
875
882
 
883
+ &.small::after {
884
+ right: 6px;
885
+ top: 8px;
886
+ width: 18px;
887
+ height: 18px;
888
+ }
889
+
890
+ &.tiny::after {
891
+ right: 6px;
892
+ top: 6px;
893
+ width: 16px;
894
+ height: 16px;
895
+ }
896
+
876
897
  &.line input {
877
898
  padding-bottom: 0;
878
899
  }
@@ -2158,4 +2179,130 @@ input:checked ~ .switch-paddle {
2158
2179
  }
2159
2180
  }
2160
2181
  }
2182
+ }
2183
+
2184
+ .searchable-dropdown-container {
2185
+ .input-container.false-select {
2186
+ font-family: $body-font-family;
2187
+ font-size: 1rem;
2188
+
2189
+ .value {
2190
+ display: block;
2191
+ padding: $form-field-padding;
2192
+ padding-right: 2rem;
2193
+ color: $body-font-color;
2194
+ background-color: $input-background-color;
2195
+ border: solid 1px $input-border-color;
2196
+ border-radius: $dealer-form-input-radius;
2197
+ line-height: 1.5rem;
2198
+ height: 44px;
2199
+ }
2200
+
2201
+ .options-list-container {
2202
+ display: none;
2203
+ position: absolute;
2204
+ width: 100%;
2205
+ z-index: 20;
2206
+ padding: 0 5px 5px;
2207
+ background-color: $input-background-color;
2208
+ border: solid 1px $input-border-color;
2209
+ border-radius: 0 0 $dealer-form-input-radius $dealer-form-input-radius;
2210
+ border-top: 0;
2211
+
2212
+ .input-container.search {
2213
+ margin-bottom: 0.5rem;
2214
+ }
2215
+
2216
+ .options-list {
2217
+ max-height: 200px;
2218
+ overflow: auto;
2219
+ margin: 0 !important;
2220
+ font-size: 1rem;
2221
+
2222
+ .option {
2223
+ display: block;
2224
+ color: $body-font-color;
2225
+ padding: 5px;
2226
+ line-height: 1.5rem;
2227
+
2228
+ &.empty {
2229
+ color: $text-gray;
2230
+ }
2231
+ }
2232
+
2233
+ a.option {
2234
+ &.active,
2235
+ &:hover {
2236
+ background: $input-highlight-color linear-gradient(0deg, $input-highlight-color 0%, $input-highlight-color 100%);
2237
+ }
2238
+ }
2239
+ }
2240
+ }
2241
+
2242
+ &.small {
2243
+ .value {
2244
+ height: 35px;
2245
+ padding-top: 5px;
2246
+ padding-bottom: 5px;
2247
+ padding-left: 5px;
2248
+ font-size: 0.875rem;
2249
+ }
2250
+
2251
+ .options-list-container .options-list {
2252
+ font-size: 0.875rem;
2253
+ }
2254
+ }
2255
+
2256
+ &.tiny {
2257
+ .value {
2258
+ height: 30px;
2259
+ padding-top: 0;
2260
+ padding-bottom: 0;
2261
+ padding-left: 0.5rem;
2262
+ font-size: 0.875rem;
2263
+ line-height: 1.75rem;
2264
+ }
2265
+
2266
+ .options-list-container .options-list {
2267
+ font-size: 0.875rem;
2268
+ }
2269
+ }
2270
+
2271
+ &.large {
2272
+ .value {
2273
+ height: 55px;
2274
+ font-size: 1.25rem;
2275
+ line-height: 2rem;
2276
+ }
2277
+
2278
+ .options-list-container .options-list {
2279
+ font-size: 1.25rem;
2280
+ }
2281
+ }
2282
+
2283
+ &.error:not(.open) {
2284
+ .value {
2285
+ border-width: 2px;
2286
+ border-color: $alert !important;
2287
+ }
2288
+
2289
+ &:not(.tiny) {
2290
+ .value {
2291
+ padding-top: calc(0.625rem - 1px);
2292
+ padding-bottom: calc(0.625rem - 1px);
2293
+ }
2294
+ }
2295
+ }
2296
+
2297
+ &.open {
2298
+ .value {
2299
+ border-radius: $dealer-form-input-radius $dealer-form-input-radius 0 0;
2300
+ border-bottom: 0 !important;
2301
+ }
2302
+
2303
+ .options-list-container {
2304
+ display: block;
2305
+ }
2306
+ }
2307
+ }
2161
2308
  }
@@ -0,0 +1,140 @@
1
+ <template>
2
+ <div :id="id + '-container'" ref="container" class="input-container searchable-dropdown-container" @focusin="focusOn" @focusout="focusOff" tabindex="0">
3
+ <div class="input-container select false-select" :class="computedClass">
4
+ <span class="value">{{ value ? value.Name : 'Select' }}</span>
5
+ <div class="options-list-container">
6
+ <div class="input-container search small">
7
+ <input ref="input" type="text" autocomplete="off" role="combobox" :aria-controls="id + '-list'" aria-autocomplete="list" :aria-expanded="focused" v-model="searchValue" :maxlength="maxLength" :disabled="disabled" />
8
+ </div>
9
+ <div class="options-list" role="listbox" :aria-label="label" :id="id + '-list'">
10
+ <span v-if="filteredOptions.length === 0" class="option empty">No {{ searchType }} found</span>
11
+ <a v-for="option in filteredOptions" :key="option.Id" role="option" class="option" :class="{ active: value && value.Id === option.Id }" @click="selectValue(option)">{{ option.Name }}</a>
12
+ </div>
13
+ </div>
14
+ </div>
15
+ </div>
16
+ </template>
17
+ <script>
18
+ export default {
19
+ name: 'SearchableDropdownInput',
20
+ props: {
21
+ id: String,
22
+ label: String,
23
+ externalValueId: String,
24
+ externalValueName: String,
25
+ loading: {
26
+ type: Boolean,
27
+ default: false,
28
+ },
29
+ options: {
30
+ type: Array,
31
+ default: () => [],
32
+ },
33
+ invalid: {
34
+ type: Boolean,
35
+ default: false,
36
+ },
37
+ maxLength: {
38
+ type: Number,
39
+ default: 200,
40
+ },
41
+ disabled: {
42
+ type: Boolean,
43
+ default: false,
44
+ },
45
+ searchType: {
46
+ type: String,
47
+ default: 'products'
48
+ },
49
+ cssClass: String,
50
+ },
51
+ data: () => {
52
+ return {
53
+ value: null,
54
+ searchValue: '',
55
+
56
+ focused: false,
57
+
58
+ filteredOptions: [],
59
+ };
60
+ },
61
+ created: function () {
62
+ if (this.externalValueId && this.externalValueName) {
63
+ this.value = { Id: this.externalValueId, Name: this.externalValueName };
64
+ }
65
+
66
+ if (this.options.length) {
67
+ this.filterResults();
68
+ }
69
+ },
70
+ methods: {
71
+ filterResults() {
72
+ let newResults = [];
73
+
74
+ if (this.searchValue) {
75
+ const search = this.searchValue.toLowerCase();
76
+
77
+ this.options.forEach(option => {
78
+ if (option.Name && option.Name.toLowerCase().indexOf(search) > -1) {
79
+ newResults.push(option);
80
+ }
81
+ });
82
+ } else {
83
+ newResults = this.options.slice();
84
+ }
85
+
86
+ this.filteredOptions.splice(0);
87
+ this.filteredOptions = this.filteredOptions.concat(newResults);
88
+ },
89
+
90
+ selectValue(value) {
91
+ this.value = value;
92
+
93
+ this.$emit('update', value);
94
+
95
+ if (this.$refs.container) {
96
+ this.$refs.container.blur();
97
+ }
98
+ this.focused = false;
99
+ },
100
+
101
+ focusInput() {
102
+ this.focused = true;
103
+ },
104
+ focusSearchInput() {
105
+ this.focused = true;
106
+ if (this.$refs.input) {
107
+ this.$refs.input.focus();
108
+ }
109
+ },
110
+ focusOn(e) {
111
+ //console.log(e.target);
112
+ this.focused = true;
113
+ },
114
+ focusOff(e) {
115
+ setTimeout(() => {
116
+ if (!this.$refs.container || !document.activeElement || (document.activeElement.id !== this.id + '-container' && !this.$refs.container.contains(document.activeElement))) {
117
+ this.focused = false;
118
+ this.searchValue = null;
119
+ }
120
+ }, 200);
121
+ },
122
+ },
123
+ computed: {
124
+ computedClass() {
125
+ return (this.cssClass || '') + (this.focused ? ' open' : '') + (this.invalid ? ' error' : '');
126
+ },
127
+ },
128
+ watch: {
129
+ loading(newValue, prevValue) {
130
+ if (!newValue && prevValue) {
131
+ this.searchValue = '';
132
+ this.filterResults();
133
+ }
134
+ },
135
+ searchValue(newValue) {
136
+ this.filterResults();
137
+ },
138
+ },
139
+ }
140
+ </script>