@eturnity/eturnity_reusable_components 7.48.1-EPDM-10964.0 → 7.48.1-EPDM-12680.12

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.
@@ -0,0 +1,225 @@
1
+ <template>
2
+ <ComponentWrapper>
3
+ <IconWrapper :size="size">
4
+ <IconImg
5
+ ref="iconImg"
6
+ @click.prevent="toggleShowInfo()"
7
+ @mouseenter="openTrigger == 'onHover' ? toggleShowInfo() : ''"
8
+ @mouseleave="openTrigger == 'onHover' ? toggleShowInfo() : ''"
9
+ >
10
+ <IconComponent
11
+ :color="iconColor"
12
+ cursor="pointer"
13
+ name="info"
14
+ :size="size"
15
+ />
16
+ </IconImg>
17
+ <TextOverlay
18
+ v-if="showInfo"
19
+ :arrow-position="arrowPosition"
20
+ :icon-size="size"
21
+ :max-width="maxWidth"
22
+ :position="overlayPosition"
23
+ :style="overlayStyle"
24
+ :width="width"
25
+ ><slot></slot>
26
+ <span v-html="text"></span>
27
+ </TextOverlay>
28
+ </IconWrapper>
29
+ </ComponentWrapper>
30
+ </template>
31
+
32
+ <script>
33
+ // import InfoText from "@eturnity/eturnity_reusable_components/src/components/infoText"
34
+ //To use:
35
+ // <info-text
36
+ // text="Veritatis et quasi architecto beatae vitae"
37
+ // size="20px"
38
+ // />
39
+ import theme from '../../assets/theme.js'
40
+ import styled from 'vue3-styled-components'
41
+ import IconComponent from '../icon'
42
+
43
+ const textAttrs = {
44
+ iconSize: String,
45
+ width: String,
46
+ position: String,
47
+ arrowPosition: String,
48
+ }
49
+ const TextOverlay = styled('div', textAttrs)`
50
+ position: absolute;
51
+ text-align: left;
52
+ background: ${(props) => props.theme.colors.black};
53
+ padding: 10px;
54
+ width: ${(props) => props.width};
55
+ max-width: ${(props) => props.maxWidth};
56
+ font-size: 13px;
57
+ font-weight: 400;
58
+ line-height: normal;
59
+ border-radius: 4px;
60
+ z-index: 9999;
61
+ color: ${(props) => props.theme.colors.white};
62
+ word-wrap: break-word;
63
+ overflow-wrap: break-word;
64
+
65
+ :before {
66
+ content: '';
67
+ background-color: ${(props) => props.theme.colors.black};
68
+ position: absolute;
69
+ ${(props) => (props.position === 'top' ? 'bottom: -4px;' : 'top: -4px;')}
70
+ ${(props) => {
71
+ switch (props.arrowPosition) {
72
+ case 'left':
73
+ return 'left: 40px;'
74
+ case 'center':
75
+ return 'left: calc(50% - 4px);'
76
+ case 'right':
77
+ return 'right: 40px;'
78
+ default:
79
+ return 'left: calc(50% - 4px);'
80
+ }
81
+ }}
82
+ height: 8px;
83
+ width: 8px;
84
+ transform-origin: center center;
85
+ transform: rotate(45deg);
86
+ }
87
+
88
+ span a {
89
+ color: #2cc0eb;
90
+ }
91
+ `
92
+
93
+ const iconAttrs = { size: String }
94
+ const IconWrapper = styled('div', iconAttrs)`
95
+ position: relative;
96
+ height: ${(props) => props.size};
97
+ `
98
+
99
+ const IconImg = styled.div`
100
+ line-height: 0;
101
+ `
102
+
103
+ const ComponentWrapper = styled.div`
104
+ display: inline-block;
105
+ `
106
+
107
+ export default {
108
+ name: 'InfoText',
109
+ components: {
110
+ IconWrapper,
111
+ TextOverlay,
112
+ ComponentWrapper,
113
+ IconImg,
114
+ IconComponent,
115
+ },
116
+ props: {
117
+ text: {
118
+ required: false,
119
+ },
120
+ size: {
121
+ required: false,
122
+ default: '14px',
123
+ },
124
+ openTrigger: {
125
+ required: false,
126
+ default: 'onHover', // onHover, onClick
127
+ },
128
+ width: {
129
+ required: false,
130
+ default: '200px',
131
+ },
132
+ maxWidth: {
133
+ type: String,
134
+ default: '400px',
135
+ },
136
+ },
137
+ data() {
138
+ return {
139
+ showInfo: false,
140
+ overlayStyle: {},
141
+ overlayPosition: 'top',
142
+ arrowPosition: 'center',
143
+ }
144
+ },
145
+ computed: {
146
+ iconColor() {
147
+ return theme.colors.mediumGray
148
+ },
149
+ },
150
+ mounted() {
151
+ window.addEventListener('resize', this.positionOverlay)
152
+ },
153
+ beforeUnmount() {
154
+ window.removeEventListener('resize', this.positionOverlay)
155
+ },
156
+ methods: {
157
+ toggleShowInfo() {
158
+ this.showInfo = !this.showInfo
159
+
160
+ if (this.showInfo) {
161
+ document.addEventListener('click', this.clickOutside)
162
+ this.$nextTick(() => {
163
+ this.positionOverlay()
164
+ })
165
+ } else {
166
+ document.removeEventListener('click', this.clickOutside)
167
+ }
168
+ },
169
+ clickOutside(event) {
170
+ if (this.$el.contains(event.target)) {
171
+ return
172
+ }
173
+ this.toggleShowInfo()
174
+ },
175
+ positionOverlay() {
176
+ const iconRect = this.$refs.iconImg.getBoundingClientRect()
177
+ const overlayRect = this.$el
178
+ .querySelector('.TextOverlay')
179
+ .getBoundingClientRect()
180
+
181
+ let top, left
182
+
183
+ // Check if there's enough space above the icon
184
+ if (
185
+ iconRect.top > overlayRect.height + 10 &&
186
+ iconRect.top > window.innerHeight / 2
187
+ ) {
188
+ top = -overlayRect.height - 10
189
+ this.overlayPosition = 'top'
190
+ } else {
191
+ // If not, position it below the icon
192
+ top = iconRect.height + 10
193
+ this.overlayPosition = 'bottom'
194
+ }
195
+
196
+ left = -(overlayRect.width / 2) + iconRect.width / 2
197
+
198
+ // Ensure the overlay doesn't go off-screen horizontally
199
+ if (iconRect.left + left < 0) {
200
+ left = -iconRect.left
201
+ this.arrowPosition = 'left'
202
+ } else if (
203
+ iconRect.left + left + overlayRect.width >
204
+ window.innerWidth
205
+ ) {
206
+ left = window.innerWidth - (iconRect.left + overlayRect.width)
207
+ this.arrowPosition = 'right'
208
+ } else {
209
+ this.arrowPosition = 'center'
210
+ }
211
+
212
+ // Adjust vertical position if it goes off-screen
213
+ const totalHeight = iconRect.top + top + overlayRect.height
214
+ if (totalHeight > window.innerHeight) {
215
+ top -= totalHeight - window.innerHeight + 10
216
+ }
217
+
218
+ this.overlayStyle = {
219
+ top: `${top}px`,
220
+ left: `${left}px`,
221
+ }
222
+ },
223
+ },
224
+ }
225
+ </script>
@@ -13,7 +13,11 @@
13
13
  </LabelSlotWrapper>
14
14
 
15
15
  <LabelWrapper v-if="labelText">
16
- <LabelText :data-id="labelDataId" :label-font-color="labelFontColor">
16
+ <LabelText
17
+ :data-id="labelDataId"
18
+ :label-font-color="labelFontColor"
19
+ :label-font-weight="labelFontWeight"
20
+ >
17
21
  {{ labelText }}
18
22
  </LabelText>
19
23
 
@@ -28,11 +32,14 @@
28
32
  v-bind="$attrs"
29
33
  ref="inputField1"
30
34
  :align-items="alignItems"
31
- :background-color="backgroundColor"
32
- :border-color="borderColor"
35
+ :background-color="
36
+ colorMode === 'transparent' ? 'transparent' : backgroundColor
37
+ "
38
+ :border-color="colorMode === 'transparent' ? 'white' : borderColor"
39
+ :color-mode="colorMode"
33
40
  :data-id="inputDataId"
34
41
  :disabled="disabled"
35
- :font-color="fontColor"
42
+ :font-color="colorMode === 'transparent' ? 'white' : fontColor"
36
43
  :font-size="fontSize"
37
44
  :has-label-slot="hasLabelSlot"
38
45
  :has-slot="hasSlot"
@@ -51,6 +58,8 @@
51
58
  @blur="onInputBlur($event)"
52
59
  @focus="focusInput()"
53
60
  @input="onInput($event)"
61
+ @keydown.down="decrementValue"
62
+ @keydown.up="incrementValue"
54
63
  @keyup.enter="onEnterPress"
55
64
  />
56
65
  <SlotContainer v-if="hasSlot" :is-error="isError" :slot-size="slotSize">
@@ -92,6 +101,31 @@
92
101
  </template>
93
102
  </RCSelect>
94
103
  </SelectWrapper>
104
+
105
+ <ArrowControls
106
+ v-if="!disabled && showArrowControls"
107
+ :color-mode="colorMode"
108
+ >
109
+ <ArrowButton @click="incrementValue">
110
+ <Icon
111
+ :color="colorMode === 'transparent' ? 'white' : undefined"
112
+ name="arrow_up"
113
+ size="8px"
114
+ />
115
+ </ArrowButton>
116
+ <ArrowDivider :color-mode="colorMode" />
117
+ <ArrowButton
118
+ :is-disabled="textInput <= minNumber"
119
+ @click="decrementValue"
120
+ >
121
+ <Icon
122
+ :color="colorMode === 'transparent' ? 'white' : undefined"
123
+ :disabled="textInput <= minNumber"
124
+ name="arrow_down"
125
+ size="8px"
126
+ />
127
+ </ArrowButton>
128
+ </ArrowControls>
95
129
  </InputWrapper>
96
130
  <ErrorMessage v-if="isError">{{ errorMessage }}</ErrorMessage>
97
131
  </Container>
@@ -123,6 +157,7 @@
123
157
  // labelInfoAlign="left"
124
158
  // :minNumber="0"
125
159
  // fontColor="blue"
160
+ // colorMode="transparent" // Makes background transparent, border white, and font white
126
161
  // >
127
162
  //<template name=label><img>....</template>
128
163
  //</inputNumber>
@@ -156,8 +191,10 @@
156
191
  isInteractive: Boolean,
157
192
  alignItems: String,
158
193
  labelFontColor: String,
194
+ labelFontWeight: String,
159
195
  borderColor: String,
160
196
  showLinearUnitName: Boolean,
197
+ colorMode: String,
161
198
  }
162
199
 
163
200
  const Container = styled('div', inputProps)`
@@ -181,15 +218,18 @@
181
218
  : '1px solid ' + props.theme.colors.grey4};
182
219
  height: ${(props) => props.inputHeight};
183
220
  max-height: ${(props) => props.inputHeight};
184
- padding: 0 10px;
185
- padding-right: ${({ slotSize, isError, showLinearUnitName }) =>
186
- slotSize
221
+ padding: ${({ colorMode }) =>
222
+ colorMode === 'transparent' ? '10px 15px' : '0 10px'};
223
+ padding-right: ${({ slotSize, isError, showLinearUnitName, colorMode }) =>
224
+ colorMode === 'transparent'
225
+ ? '0'
226
+ : slotSize
187
227
  ? isError && !showLinearUnitName
188
228
  ? 'calc(' + slotSize + ' + 24px)'
189
229
  : 'calc(' + slotSize + ' + 10px)'
190
230
  : isError && !showLinearUnitName
191
231
  ? '24px'
192
- : '5px'};
232
+ : '40px'};
193
233
  border-radius: ${(props) =>
194
234
  props.isInteractive && props.alignItems != 'vertical'
195
235
  ? '0 4px 4px 0'
@@ -206,14 +246,16 @@
206
246
  ? props.fontColor + ' !important'
207
247
  : props.theme.colors.black};
208
248
  background-color: ${(props) =>
209
- props.backgroundColor
249
+ props.isDisabled
250
+ ? props.theme.colors.disabled + ' !important'
251
+ : props.backgroundColor
210
252
  ? props.backgroundColor + ' !important'
211
253
  : props.theme.colors.white};
212
254
  width: ${(props) =>
213
255
  props.inputWidth && !props.hasLabelSlot ? props.inputWidth : '100%'};
214
256
  min-width: ${(props) => (props.minWidth ? props.minWidth : 'unset')};
215
257
  background-color: ${(props) =>
216
- props.isDisabled ? props.theme.colors.grey5 : '#fff'};
258
+ props.isDisabled ? props.theme.colors.grey5 : props.theme.colors.white};
217
259
  box-sizing: border-box;
218
260
 
219
261
  &::placeholder {
@@ -225,6 +267,55 @@
225
267
  }
226
268
  `
227
269
 
270
+ const ArrowControlsProps = {
271
+ colorMode: String,
272
+ }
273
+ const ArrowControls = styled('div', ArrowControlsProps)`
274
+ position: absolute;
275
+ right: 0;
276
+ top: 0;
277
+ bottom: 0;
278
+ display: grid;
279
+ grid-template-rows: 1fr auto 1fr;
280
+ align-items: center;
281
+ justify-items: center;
282
+ cursor: pointer;
283
+ width: 30px;
284
+ background-color: ${(props) =>
285
+ props.colorMode === 'transparent'
286
+ ? 'transparent'
287
+ : props.theme.colors.white};
288
+ border-left: 1px solid
289
+ ${(props) =>
290
+ props.colorMode === 'transparent'
291
+ ? props.theme.colors.white
292
+ : props.theme.colors.black};
293
+ `
294
+
295
+ const ArrowButtonProps = {
296
+ isDisabled: Boolean,
297
+ }
298
+ const ArrowButton = styled('button', ArrowButtonProps)`
299
+ background: transparent;
300
+ opacity: ${(props) => (props.isDisabled ? '0.2' : '1')};
301
+ cursor: ${(props) => (props.isDisabled ? 'not-allowed' : 'pointer')};
302
+ display: flex;
303
+ align-items: center;
304
+ justify-content: center;
305
+ padding: 0;
306
+ width: 100%;
307
+ height: 100%;
308
+ `
309
+
310
+ const ArrowDivider = styled('div', ArrowControlsProps)`
311
+ width: 100%;
312
+ height: 1px;
313
+ background-color: ${(props) =>
314
+ props.colorMode === 'transparent'
315
+ ? props.theme.colors.white
316
+ : props.theme.colors.black};
317
+ `
318
+
228
319
  const InputWrapper = styled.span`
229
320
  position: relative;
230
321
  `
@@ -307,7 +398,7 @@
307
398
  props.theme.colors[props.labelFontColor]
308
399
  ? props.theme.colors[props.labelFontColor]
309
400
  : props.labelFontColor};
310
- font-weight: 700;
401
+ font-weight: ${(props) => props.labelFontWeight};
311
402
  `
312
403
 
313
404
  const IconAttrs = { size: String, marginRight: Number }
@@ -359,140 +450,184 @@
359
450
  SelectWrapper,
360
451
  SelectText,
361
452
  Divider,
453
+ ArrowControls,
454
+ ArrowButton,
455
+ ArrowDivider,
362
456
  },
363
457
  inheritAttrs: false,
364
458
  props: {
365
459
  placeholder: {
460
+ type: String,
366
461
  required: false,
367
462
  default: '',
368
463
  },
369
464
  isError: {
465
+ type: Boolean,
370
466
  required: false,
371
467
  default: false,
372
468
  },
373
469
  inputWidth: {
470
+ type: String,
374
471
  required: false,
375
472
  default: null,
376
473
  },
377
474
  minWidth: {
475
+ type: String,
378
476
  required: false,
379
477
  default: null,
380
478
  },
381
479
  inputHeight: {
480
+ type: String,
382
481
  required: false,
383
482
  default: '40px',
384
483
  },
385
484
  value: {
485
+ type: [String, Number],
386
486
  required: true,
387
487
  default: null,
388
488
  },
389
489
  clearInput: {
490
+ type: Boolean,
390
491
  required: false,
391
492
  default: false,
392
493
  },
393
494
  alignItems: {
495
+ type: String,
394
496
  required: false,
395
497
  default: 'vertical',
396
498
  },
397
499
  errorMessage: {
500
+ type: String,
398
501
  required: false,
399
502
  default: 'Please insert a correct number',
400
503
  },
401
504
  numberPrecision: {
505
+ type: Number,
402
506
  required: false,
403
507
  default: 0,
404
508
  },
405
509
  minDecimals: {
510
+ type: Number,
406
511
  required: false,
407
512
  default: 0,
408
513
  },
409
514
  unitName: {
515
+ type: String,
410
516
  required: false,
411
517
  default: '',
412
518
  },
413
519
  showLinearUnitName: {
520
+ type: Boolean,
414
521
  required: false,
415
522
  default: false,
416
523
  },
417
524
  disabled: {
525
+ type: Boolean,
418
526
  required: false,
419
527
  default: false,
420
528
  },
421
529
  noBorder: {
530
+ type: Boolean,
422
531
  required: false,
423
532
  default: false,
424
533
  },
425
534
  borderColor: {
535
+ type: String,
426
536
  required: false,
537
+ default: null,
427
538
  },
428
539
  textAlign: {
540
+ type: String,
429
541
  required: false,
430
542
  default: 'left',
431
543
  },
432
544
  fontSize: {
545
+ type: String,
433
546
  required: false,
434
547
  default: '13px',
435
548
  },
436
549
  isInteractive: {
550
+ type: Boolean,
437
551
  required: false,
438
552
  default: false,
439
553
  },
440
554
  interactionStep: {
555
+ type: Number,
441
556
  required: false,
442
557
  default: 1,
443
558
  },
444
559
  labelText: {
560
+ type: String,
445
561
  required: false,
446
562
  default: null,
447
563
  },
448
564
  labelInfoText: {
565
+ type: String,
449
566
  required: false,
450
567
  default: null,
451
568
  },
452
569
  labelInfoAlign: {
570
+ type: String,
453
571
  required: false,
454
572
  default: 'left',
455
573
  },
456
574
  defaultNumber: {
575
+ type: Number,
457
576
  required: false,
458
577
  default: null,
459
578
  },
460
579
  minNumber: {
580
+ type: Number,
461
581
  required: false,
462
582
  default: null,
463
583
  },
464
584
  fontColor: {
585
+ type: String,
465
586
  required: false,
466
587
  default: null,
467
588
  },
468
589
  backgroundColor: {
590
+ type: String,
469
591
  required: false,
470
592
  default: null,
471
593
  },
472
594
  numberToStringEnabled: {
595
+ type: Boolean,
473
596
  required: false,
474
597
  default: true,
475
598
  },
476
599
  allowNegative: {
600
+ type: Boolean,
477
601
  required: false,
478
602
  default: true,
479
603
  },
480
604
  slotSize: {
605
+ type: String,
481
606
  required: false,
607
+ default: null,
482
608
  },
483
609
  labelFontColor: {
610
+ type: String,
484
611
  required: false,
485
612
  default: 'eturnityGrey',
486
613
  },
614
+ labelFontWeight: {
615
+ type: String,
616
+ required: false,
617
+ default: '700',
618
+ },
487
619
  focus: {
620
+ type: Boolean,
488
621
  required: false,
489
622
  default: false,
490
623
  },
491
624
  labelDataId: {
625
+ type: String,
492
626
  required: false,
493
627
  default: '',
494
628
  },
495
629
  inputDataId: {
630
+ type: String,
496
631
  required: false,
497
632
  default: '',
498
633
  },
@@ -516,6 +651,14 @@
516
651
  type: Boolean,
517
652
  default: false,
518
653
  },
654
+ colorMode: {
655
+ type: String,
656
+ default: '',
657
+ },
658
+ showArrowControls: {
659
+ type: Boolean,
660
+ default: false,
661
+ },
519
662
  },
520
663
  data() {
521
664
  return {
@@ -585,6 +728,36 @@
585
728
  }
586
729
  },
587
730
  methods: {
731
+ incrementValue() {
732
+ const currentValue = Math.max(
733
+ parseFloat(this.textInput || 0),
734
+ this.minNumber || 0
735
+ )
736
+ const newValue = currentValue + this.interactionStep
737
+ this.textInput = numberToString({
738
+ value: newValue,
739
+ numberPrecision: this.numberPrecision,
740
+ minDecimals: this.minDecimals,
741
+ })
742
+ this.$emit('on-input', newValue)
743
+ this.$emit('input-change', newValue)
744
+ },
745
+ decrementValue() {
746
+ const currentValue = Math.max(
747
+ parseFloat(this.textInput || 0),
748
+ this.minNumber || 0
749
+ )
750
+ const newValue = currentValue - this.interactionStep
751
+ if (this.allowNegative || newValue >= 0) {
752
+ this.textInput = numberToString({
753
+ value: newValue,
754
+ numberPrecision: this.numberPrecision,
755
+ minDecimals: this.minDecimals,
756
+ })
757
+ this.$emit('on-input', newValue)
758
+ this.$emit('input-change', newValue)
759
+ }
760
+ },
588
761
  onEnterPress() {
589
762
  this.$emit('on-enter-click')
590
763
  this.$refs.inputField1.$el.blur()
@@ -680,6 +853,7 @@
680
853
  this.$emit('on-input', evaluatedVal)
681
854
  }
682
855
  }
856
+ this.textInput = evaluatedVal
683
857
  },
684
858
  onInputBlur(e) {
685
859
  this.isFocused = false