@rypen-dev/shared-components 4.0.2 → 4.0.3

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": "4.0.2",
4
+ "version": "4.0.3",
5
5
  "main": "./dist/index.js",
6
6
  "scripts": {
7
7
  "build": "webpack --config ./webpack.config.js",
@@ -9,7 +9,7 @@
9
9
  },
10
10
  "dependencies": {
11
11
  "@fortawesome/fontawesome-free": "6.4.2",
12
- "@rypen-dev/helpers": "1.0.19",
12
+ "@rypen-dev/helpers": "1.0.21",
13
13
  "foundation-sites": "6.8.1",
14
14
  "moment": "2.29.4",
15
15
  "vue": "3.3.4"
@@ -272,6 +272,27 @@ a.info {
272
272
  transition: border-color 300ms, right 300ms;
273
273
  }
274
274
 
275
+ img {
276
+ height: 1.25rem;
277
+ margin: -0.75rem 0.25rem 0 0;
278
+ position: relative;
279
+ top: 0.25rem;
280
+ }
281
+
282
+ &:hover,
283
+ &:focus {
284
+ color: $call-to-action-color;
285
+
286
+ &::before {
287
+ right: -10px;
288
+ width: $arrow-width + 10px;
289
+ }
290
+
291
+ &::after {
292
+ right: -9px;
293
+ }
294
+ }
295
+
275
296
  &.short {
276
297
  padding-right: $short-arrow-width + 10px;
277
298
 
@@ -303,20 +324,6 @@ a.info {
303
324
  }
304
325
  }
305
326
 
306
- &:hover,
307
- &:focus {
308
- color: $call-to-action-color;
309
-
310
- &::before {
311
- right: -10px;
312
- width: $arrow-width + 10px;
313
- }
314
-
315
- &::after {
316
- right: -9px;
317
- }
318
- }
319
-
320
327
  &.no-arrow {
321
328
  padding-right: 0;
322
329
 
@@ -364,11 +371,11 @@ a.info {
364
371
 
365
372
  &::after {
366
373
  }
367
- }
368
374
 
369
- &.reversed {
370
- padding-right: 0;
371
- padding-left: 20px;
375
+ &.reversed {
376
+ padding-right: 0;
377
+ padding-left: 20px;
378
+ }
372
379
  }
373
380
  }
374
381
 
@@ -441,6 +448,12 @@ a.info {
441
448
  }
442
449
  }
443
450
 
451
+ img {
452
+ height: 1.5rem;
453
+ margin-top: -0.5rem;
454
+ margin-right: 0.5rem;
455
+ }
456
+
444
457
  &.drop-down {
445
458
  &::after {
446
459
  border-bottom-width: 2px;
@@ -462,6 +475,28 @@ a.info {
462
475
  }
463
476
  }
464
477
  }
478
+
479
+ @media print, screen and (min-width: map-get($breakpoints, medium)) and (max-width: map-get($breakpoints, large) - 1px) {
480
+ &.medium-only-small-text {
481
+ font-size: 0.875rem;
482
+ }
483
+
484
+ &.medium-only-no-tail {
485
+ padding-right: 20px;
486
+
487
+ &::before {
488
+ display: none;
489
+ }
490
+
491
+ &::after {
492
+ }
493
+
494
+ &.reversed {
495
+ padding-right: 0;
496
+ padding-left: 20px;
497
+ }
498
+ }
499
+ }
465
500
  }
466
501
 
467
502
  button,
@@ -222,6 +222,24 @@ select {
222
222
  }
223
223
  }
224
224
  }
225
+
226
+ &.reversed {
227
+ label {
228
+ padding-left: 0;
229
+ padding-right: 45px;
230
+
231
+ &::before,
232
+ &::after {
233
+ left: auto;
234
+ right: 0;
235
+ }
236
+
237
+ }
238
+
239
+ &.small label {
240
+ padding-right: 35px;
241
+ }
242
+ }
225
243
  }
226
244
 
227
245
  .checkbox-group {
@@ -711,7 +729,7 @@ label {
711
729
  display: block;
712
730
  position: absolute;
713
731
  right: 8px;
714
- top: 8px;
732
+ top: 10px;
715
733
  width: 24px;
716
734
  height: 24px;
717
735
  }
@@ -915,14 +933,6 @@ select {
915
933
  width: 46px;
916
934
  height: 46px;
917
935
 
918
- body.hover-capable &:hover {
919
- border-color: $secondary-alt;
920
-
921
- .preview {
922
- display: block;
923
- }
924
- }
925
-
926
936
  &::before {
927
937
  position: absolute;
928
938
  top: -2px;
@@ -940,8 +950,7 @@ select {
940
950
  }
941
951
  }
942
952
 
943
- a,
944
- span {
953
+ a {
945
954
  display: block;
946
955
  width: 36px;
947
956
  height: 36px;
@@ -952,9 +961,10 @@ select {
952
961
  display: none;
953
962
  position: absolute;
954
963
  padding-bottom: 17px;
955
- bottom: calc(100% + 5px);
964
+ bottom: calc(100% + 6px);
956
965
  left: 50%;
957
966
  transform: translateX(-50%);
967
+ pointer-events: none; // to make it easier to scan through options
958
968
  z-index: 101;
959
969
 
960
970
  @include tooltip-arrow('down');
@@ -997,6 +1007,19 @@ select {
997
1007
  }
998
1008
  }
999
1009
  }
1010
+
1011
+ .zoom {
1012
+ position: absolute;
1013
+ top: 12px;
1014
+ right: 12px;
1015
+ border-radius: 50%;
1016
+ background-color: fade-out($tertiary-alt, 0.4);
1017
+ font-size: 1rem;
1018
+ line-height: 1rem;
1019
+ text-align: center;
1020
+ padding: 8px;
1021
+ z-index: 62;
1022
+ }
1000
1023
  }
1001
1024
 
1002
1025
  &.disabled {
@@ -1013,8 +1036,7 @@ select {
1013
1036
  bottom: 4px;
1014
1037
  }
1015
1038
 
1016
- a,
1017
- span {
1039
+ a {
1018
1040
  cursor: default;
1019
1041
 
1020
1042
  &::before {
@@ -1061,6 +1083,10 @@ select {
1061
1083
  }
1062
1084
  }
1063
1085
  }
1086
+
1087
+ &.fillers {
1088
+ height: 0;
1089
+ }
1064
1090
  }
1065
1091
 
1066
1092
  &.tiny {
@@ -1076,17 +1102,64 @@ select {
1076
1102
  height: 26px;
1077
1103
  }
1078
1104
 
1079
- a,
1080
- span {
1105
+ a {
1081
1106
  width: 18px;
1082
1107
  height: 18px;
1083
1108
  }
1084
1109
  }
1085
1110
  }
1086
1111
 
1112
+ &.large {
1113
+ li {
1114
+ width: 86px;
1115
+ height: 86px;
1116
+ padding: 6px;
1117
+ margin-right: 8px;
1118
+ margin-bottom: 8px;
1119
+
1120
+ &::before {
1121
+ width: 88px;
1122
+ height: 88px;
1123
+ top: -2px;
1124
+ left: -2px;
1125
+ border-width: 2px;
1126
+ }
1127
+
1128
+ a {
1129
+ width: 72px;
1130
+ height: 72px;
1131
+
1132
+ .preview {
1133
+ bottom: calc(100% + 10px);
1134
+
1135
+ .preview-name {
1136
+ padding: 6px;
1137
+ }
1138
+ }
1139
+ }
1140
+ }
1141
+
1142
+ @media (min-width: map-get($breakpoints, large)) {
1143
+ li a .preview {
1144
+ .preview-image {
1145
+ width: 300px;
1146
+ height: 300px;
1147
+ }
1148
+ }
1149
+ }
1150
+
1151
+ @media (min-width: map-get($breakpoints, xlarge)) {
1152
+ li a .preview {
1153
+ .preview-image {
1154
+ width: 400px;
1155
+ height: 400px;
1156
+ }
1157
+ }
1158
+ }
1159
+ }
1160
+
1087
1161
  @media screen and (max-width: map-get($breakpoints, medium) - 1px) {
1088
- a,
1089
- span {
1162
+ a {
1090
1163
  .preview {
1091
1164
  display: none !important;
1092
1165
  }
@@ -1100,8 +1173,7 @@ select {
1100
1173
  width: 40px;
1101
1174
  height: 40px;
1102
1175
 
1103
- a,
1104
- span {
1176
+ a {
1105
1177
  width: 30px;
1106
1178
  height: 30px;
1107
1179
  }
@@ -1114,6 +1186,31 @@ select {
1114
1186
  }
1115
1187
  }
1116
1188
 
1189
+ body.hover-capable {
1190
+ .swatch-list {
1191
+ li {
1192
+ a .zoom {
1193
+ display: none;
1194
+ }
1195
+
1196
+ &:hover {
1197
+ border-color: $secondary-alt;
1198
+
1199
+ a {
1200
+ .preview,
1201
+ .zoom {
1202
+ display: block;
1203
+ }
1204
+ }
1205
+ }
1206
+ }
1207
+
1208
+ &.library li:hover > div {
1209
+ border-color: $secondary-alt;
1210
+ }
1211
+ }
1212
+ }
1213
+
1117
1214
  .payment-display {
1118
1215
  span {
1119
1216
  display: inline-block;
@@ -1454,6 +1551,12 @@ select {
1454
1551
  }
1455
1552
  }
1456
1553
 
1554
+ &.success-alt {
1555
+ input:checked ~ .switch-paddle {
1556
+ background-color: $success-alt;
1557
+ }
1558
+ }
1559
+
1457
1560
  &.warning {
1458
1561
  input:checked ~ .switch-paddle {
1459
1562
  background-color: $warning;
@@ -1463,6 +1566,12 @@ select {
1463
1566
  &.no-margin {
1464
1567
  margin-bottom: 0 !important;
1465
1568
  }
1569
+
1570
+ &.false-gray {
1571
+ .switch-paddle {
1572
+ background-color: $text-gray;
1573
+ }
1574
+ }
1466
1575
  }
1467
1576
 
1468
1577
  .switch-paddle {
@@ -1597,4 +1706,90 @@ input:checked ~ .switch-paddle {
1597
1706
  &.no-margin {
1598
1707
  margin-bottom: 0 !important;
1599
1708
  }
1709
+ }
1710
+
1711
+ .lookup-container {
1712
+ position: relative;
1713
+
1714
+ .input-container {
1715
+ position: relative;
1716
+
1717
+ &.suggestions > input[type='text'] {
1718
+ border-radius: $global-radius $global-radius 0 0;
1719
+ }
1720
+
1721
+ &.loading .mini-loader {
1722
+ position: absolute;
1723
+ top: 12px;
1724
+ right: 0.625rem;
1725
+ }
1726
+
1727
+ &.small {
1728
+ .mini-loader {
1729
+ top: 8px;
1730
+ right: 5px;
1731
+ }
1732
+ }
1733
+ }
1734
+
1735
+ &.small {
1736
+ .lookup-suggestions {
1737
+ top: 35px;
1738
+ padding: 0 2px 3px;
1739
+ font-size: 0.875rem;
1740
+
1741
+ ul li {
1742
+ a {
1743
+ padding: 2px;
1744
+ }
1745
+
1746
+ &.empty {
1747
+ padding: 2px;
1748
+ }
1749
+ }
1750
+ }
1751
+ }
1752
+
1753
+ .lookup-suggestions {
1754
+ position: absolute;
1755
+ left: 0;
1756
+ right: 0;
1757
+ top: 44px;
1758
+ background-color: $input-background-color;
1759
+ border: solid 1px $input-border-focus-color;
1760
+ border-top: 0;
1761
+ border-radius: 0 0 $global-radius $global-radius;
1762
+ padding: 0 10px 0.625rem;
1763
+ margin-top: -1px;
1764
+ z-index: 10;
1765
+
1766
+ ul {
1767
+ max-height: 250px;
1768
+ overflow: auto;
1769
+ display: block;
1770
+ list-style-type: none;
1771
+ margin: 0;
1772
+ padding: 0;
1773
+
1774
+ li {
1775
+ display: block;
1776
+ line-height: 1.4;
1777
+ margin-bottom: 1px;
1778
+
1779
+ a {
1780
+ display: block;
1781
+ padding: 4px 6px;
1782
+
1783
+ &:hover {
1784
+ background-color: $medium-gray;
1785
+ }
1786
+ }
1787
+
1788
+ &.empty {
1789
+ color: $text-gray;
1790
+ padding: 4px 6px;
1791
+ }
1792
+ }
1793
+ }
1794
+ }
1600
1795
  }
@@ -0,0 +1,32 @@
1
+ <template>
2
+ <div class="input-container" :class="cssClass">
3
+ <input type="text" v-model="value" />
4
+ </div>
5
+ </template>
6
+ <script>
7
+ import { debounce } from "@rypen-dev/helpers";
8
+
9
+ export default {
10
+ name: 'DebouncedTextBox',
11
+ props: {
12
+ cssClass: String,
13
+ },
14
+ data: () => {
15
+ return {
16
+ value: '',
17
+ debouncedValue: '',
18
+ };
19
+ },
20
+ created: function() {
21
+ this.debouncedAction = debounce(value => {
22
+ this.debouncedValue = value;
23
+ this.$emit('change', value);
24
+ });
25
+ },
26
+ watch: {
27
+ value(newValue) {
28
+ this.debouncedAction(newValue);
29
+ },
30
+ },
31
+ };
32
+ </script>
@@ -0,0 +1,84 @@
1
+ <template>
2
+ <div class="lookup-container" :class="{ small: small }">
3
+ <div class="input-container" :class="{ loading: loading, suggestions: suggestionsOpen, small: small }">
4
+ <input type="text" autocomplete="off" v-model="value" @focus="focusOn" @blur="focusOff" />
5
+ <span v-if="loading" class="mini-loader"></span>
6
+ </div>
7
+ <div v-if="suggestionsOpen" class="lookup-suggestions">
8
+ <ul>
9
+ <li v-if="suggestions.length === 0" class="empty">No products found</li>
10
+ <li v-for="suggestion in suggestions" :key="suggestion.Id"><a @click="selectSuggestion(suggestion)">{{ suggestion.Name }}</a></li>
11
+ </ul>
12
+ </div>
13
+ </div>
14
+ </template>
15
+ <script>
16
+ import { debounce } from "@rypen-dev/helpers";
17
+
18
+ export default {
19
+ name: 'LookupTextBox',
20
+ props: {
21
+ loading: {
22
+ type: Boolean,
23
+ default: false,
24
+ },
25
+ suggestions: {
26
+ type: Array,
27
+ default: () => [],
28
+ },
29
+ error: String,
30
+ minimumLength: {
31
+ type: Number,
32
+ default: 3,
33
+ },
34
+ small: {
35
+ type: Boolean,
36
+ default: false,
37
+ },
38
+ },
39
+ data: () => {
40
+ return {
41
+ value: '',
42
+ debouncedValue: '',
43
+
44
+ focused: false,
45
+ };
46
+ },
47
+ created: function () {
48
+ this.debouncedGetSuggestions = debounce(value => {
49
+ this.debouncedValue = value;
50
+ this.getSuggestions();
51
+ });
52
+ },
53
+ methods: {
54
+ getSuggestions() {
55
+ if (this.value.length === 0 || this.value.length >= this.minimumLength) {
56
+ this.$emit('search', this.value);
57
+ }
58
+ },
59
+ selectSuggestion(suggestion) {
60
+ this.$emit('select', suggestion);
61
+ },
62
+
63
+ focusOn() {
64
+ this.focused = true;
65
+ },
66
+ focusOff() {
67
+ setTimeout(() => {
68
+ this.focused = false;
69
+ this.value = '';
70
+ }, 200);
71
+ },
72
+ },
73
+ computed: {
74
+ suggestionsOpen() {
75
+ return this.debouncedValue && this.debouncedValue.length >= this.minimumLength && this.focused && (!this.loading || this.suggestions.length > 0);
76
+ }
77
+ },
78
+ watch: {
79
+ value(newValue) {
80
+ this.debouncedGetSuggestions(newValue);
81
+ },
82
+ },
83
+ }
84
+ </script>
@@ -0,0 +1,25 @@
1
+ <template>
2
+ <div>
3
+ <generic-loader v-if="generic" :cssClass="cssClass" />
4
+ <branded-loader v-else />
5
+ </div>
6
+ </template>
7
+ <script>
8
+ import BrandedLoader from "./Loader.vue";
9
+ import GenericLoader from "./GenericLoader.vue";
10
+
11
+ export default {
12
+ name: 'VariableLoader',
13
+ props: {
14
+ cssClass: String,
15
+ generic: {
16
+ type: Boolean,
17
+ default: false,
18
+ },
19
+ },
20
+ components: {
21
+ BrandedLoader,
22
+ GenericLoader,
23
+ }
24
+ };
25
+ </script>