@eturnity/eturnity_reusable_components 7.24.3-EPDM-11320.3 → 7.24.3-EPDM-11320.4

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,6 +1,6 @@
1
1
  {
2
2
  "name": "@eturnity/eturnity_reusable_components",
3
- "version": "7.24.3-EPDM-11320.3",
3
+ "version": "7.24.3-EPDM-11320.4",
4
4
  "private": false,
5
5
  "scripts": {
6
6
  "dev": "vue-cli-service serve",
@@ -19,17 +19,17 @@
19
19
  </template>
20
20
 
21
21
  <script>
22
- // To use:
23
- // import MainButton from "@eturnity/eturnity_reusable_components/src/components/buttons/mainButton"
24
- // <main-button
25
- // text="Click Me"
26
- // customColor="#ab5348"
27
- // type="secondary" // primary, secondary, cancel
28
- // icon="icon-name" // icon name from icon component
29
- // :isDisabled="true"
30
- // :minWidth="minWidth"
31
- // :data-id="test_data_id"
32
- // />
22
+ // To use:
23
+ // import RCMainButton from "@eturnity/eturnity_reusable_components/src/components/buttons/mainButton"
24
+ // <RCMainButton
25
+ // text="Click Me"
26
+ // customColor="#ab5348"
27
+ // type="secondary" // primary, secondary, cancel
28
+ // icon="icon-name" // icon name from icon component
29
+ // :isDisabled="true"
30
+ // :minWidth="minWidth"
31
+ // :data-id="test_data_id"
32
+ // />
33
33
 
34
34
  import styled from 'vue3-styled-components'
35
35
  import Icon from '../../icon'
@@ -302,17 +302,17 @@
302
302
  import theme from '@/assets/theme.js'
303
303
  import VueDatePicker from '@vuepic/vue-datepicker'
304
304
 
305
- const ContainerWrapper = styled.div`
306
- position: absolute;
307
- margin-top: 4px;
308
- background-color: ${(props) => props.theme.colors.white};
309
- min-width: 100%;
310
- width: max-content;
311
- border: 1px solid ${(props) => props.theme.colors.grey4};
312
- border-radius: 4px;
313
- z-index: 9999;
314
- font-size: 13px;
315
- `
305
+ const ContainerWrapper = styled.div`
306
+ position: absolute;
307
+ margin-top: 4px;
308
+ background-color: ${(props) => props.theme.colors.white};
309
+ min-width: 100%;
310
+ width: max-content;
311
+ border: 1px solid ${(props) => props.theme.colors.grey4};
312
+ border-radius: 4px;
313
+ z-index: 99999;
314
+ font-size: 13px;
315
+ `
316
316
 
317
317
  const ColAttrs = { numCols: Number, hasActiveView: Boolean }
318
318
  const ColumnWrapper = styled('div', ColAttrs)`
@@ -104,12 +104,24 @@
104
104
  })`
105
105
  animation: ${(props) => props.animation};
106
106
  width: 100%;
107
- svg {
108
- width: 100%;
109
- height: 100%;
110
- background-color: ${(props) =>
111
- props.backgroundColor ? props.backgroundColor : 'transparent'};
112
- padding: ${(props) => (props.backgroundColor ? '3px' : '0')};
107
+ height: 100%;
108
+ background-color: ${(props) =>
109
+ props.backgroundColor ? props.backgroundColor : 'transparent'};
110
+ padding: ${(props) => (props.backgroundColor ? '3px' : '0')};
111
+ }
112
+ svg path {
113
+ ${({ theme, color }) => color && `fill: ${theme.colors[color] || color};`}
114
+ }
115
+ &:hover svg path {
116
+ ${({ theme, hoveredColor }) =>
117
+ hoveredColor && `fill: ${theme.colors[hoveredColor] || hoveredColor};`}
118
+ }
119
+ &:hover + div {
120
+ background-color: ${(props) => props.hoveredColor};
121
+ }
122
+ @keyframes fade {
123
+ 50% {
124
+ opacity: 0.3;
113
125
  }
114
126
  svg path {
115
127
  ${({ theme, color }) => color && `fill: ${theme.colors[color] || color};`}
@@ -1,6 +1,6 @@
1
1
  <template>
2
2
  <InfoContainer>
3
- <RCIcon name="info" size="24px" />
3
+ <RCIcon name="info" size="24px" :color="color" />
4
4
  <TextContainer>
5
5
  <slot></slot>
6
6
  </TextContainer>
@@ -31,5 +31,10 @@
31
31
  InfoContainer,
32
32
  TextContainer,
33
33
  },
34
+ props: {
35
+ color: {
36
+ required: false
37
+ }
38
+ }
34
39
  }
35
40
  </script>
@@ -6,16 +6,21 @@
6
6
  @mouseenter="openTrigger == 'onHover' ? toggleShowInfo() : ''"
7
7
  @mouseleave="openTrigger == 'onHover' ? toggleShowInfo() : ''"
8
8
  >
9
- <RCIcon :color="iconColor" cursor="pointer" name="info" :size="size" />
9
+ <IconComponent
10
+ :color="iconColor"
11
+ cursor="pointer"
12
+ name="info"
13
+ :size="size"
14
+ />
10
15
  </IconImg>
11
16
  <TextOverlay
12
17
  v-if="showInfo"
13
18
  :align-arrow="alignArrow"
14
19
  :half-computed-text-info-width="halfComputedTextInfoWidth"
15
20
  :icon-size="size"
21
+ :max-width="maxWidth"
16
22
  :width="width"
17
- >
18
- <slot></slot>
23
+ ><slot></slot>
19
24
  <span v-html="text"></span>
20
25
  </TextOverlay>
21
26
  </IconWrapper>
@@ -32,7 +37,7 @@
32
37
  // />
33
38
  import theme from '../../assets/theme.js'
34
39
  import styled from 'vue3-styled-components'
35
- import RCIcon from '../icon'
40
+ import IconComponent from '../icon'
36
41
 
37
42
  const textAttrs = {
38
43
  iconSize: String,
@@ -53,7 +58,7 @@
53
58
  background: ${(props) => props.theme.colors.black};
54
59
  padding: 10px;
55
60
  width: ${(props) => props.width};
56
- max-width: 400px;
61
+ max-width: ${(props) => props.maxWidth};
57
62
  font-size: 13px;
58
63
  font-weight: 400;
59
64
  line-height: normal;
@@ -104,7 +109,7 @@
104
109
  TextOverlay,
105
110
  ComponentWrapper,
106
111
  IconImg,
107
- RCIcon,
112
+ IconComponent,
108
113
  },
109
114
  props: {
110
115
  text: {
@@ -126,6 +131,10 @@
126
131
  required: false,
127
132
  default: '165px',
128
133
  },
134
+ maxWidth: {
135
+ type: String,
136
+ default: '400px',
137
+ },
129
138
  },
130
139
  data() {
131
140
  return {
@@ -1,5 +1,5 @@
1
1
  <template>
2
- <ComponentWrapper>
2
+ <ComponentWrapper @click.stop>
3
3
  <Container
4
4
  :background-color="backgroundColor"
5
5
  :check-color="checkColor"
@@ -61,16 +61,38 @@
61
61
  v-if="unitName && showLinearUnitName && !hasSlot"
62
62
  :has-length="!!textInput.length"
63
63
  :is-error="isError"
64
+ >{{ unitName }}</UnitContainer
65
+ >
66
+ <IconWrapper
67
+ v-if="isError && !showLinearUnitName"
68
+ :margin-right="showSelect ? selectWidth : 0"
69
+ size="16px"
64
70
  >
65
- {{ unitName }}
66
- </UnitContainer>
67
- <IconWrapper v-if="isError && !showLinearUnitName" size="16px">
68
71
  <Icon cursor="default" name="warning" size="16px" />
69
72
  </IconWrapper>
73
+ <SelectWrapper v-if="showSelect">
74
+ <Divider />
75
+ <Select
76
+ :select-width="`${selectWidth}px`"
77
+ :show-border="false"
78
+ @input-change="$emit('select-change', $event)"
79
+ >
80
+ <template #selector>
81
+ <SelectText>{{ getSelectValue }}</SelectText>
82
+ </template>
83
+ <template #dropdown>
84
+ <Option
85
+ v-for="item in selectOptions"
86
+ :key="item.value"
87
+ :value="item.value"
88
+ >
89
+ {{ item.label }}
90
+ </Option>
91
+ </template>
92
+ </Select>
93
+ </SelectWrapper>
70
94
  </InputWrapper>
71
- <ErrorMessage v-if="isError">
72
- {{ errorMessage }}
73
- </ErrorMessage>
95
+ <ErrorMessage v-if="isError">{{ errorMessage }}</ErrorMessage>
74
96
  </Container>
75
97
  </template>
76
98
 
@@ -110,6 +132,8 @@
110
132
  } from '../../../helpers/numberConverter'
111
133
  import InfoText from '../../infoText'
112
134
  import ErrorMessage from '../../errorMessage'
135
+ import Select from '../select'
136
+ import Option from '../select/option'
113
137
  import warningIcon from '../../../assets/icons/error_icon.png'
114
138
  import Icon from '../../icon'
115
139
 
@@ -285,16 +309,35 @@
285
309
  font-weight: 700;
286
310
  `
287
311
 
288
- const IconAttrs = { size: String }
312
+ const IconAttrs = { size: String, marginRight: Number }
289
313
  const IconWrapper = styled('div', IconAttrs)`
290
314
  position: absolute;
291
315
  top: 0;
292
316
  bottom: 0;
293
317
  margin: auto;
294
- right: 5px;
318
+ right: ${(props) => props.marginRight + 10}px;
295
319
  height: ${(props) => (props.size ? props.size : 'auto')};
296
320
  `
297
321
 
322
+ const SelectText = styled.div`
323
+ font-size: 13px;
324
+ `
325
+
326
+ const SelectWrapper = styled.div`
327
+ position: absolute;
328
+ top: 2px;
329
+ right: 2px;
330
+ display: flex;
331
+ height: 100%;
332
+ `
333
+
334
+ const Divider = styled.div`
335
+ margin-top: 6px;
336
+ height: calc(100% - 16px);
337
+ width: 1px;
338
+ background-color: ${({ theme }) => theme.colors.grey4};
339
+ `
340
+
298
341
  export default {
299
342
  name: 'InputNumber',
300
343
  components: {
@@ -310,6 +353,11 @@
310
353
  Icon,
311
354
  SlotContainer,
312
355
  IconWrapper,
356
+ Select,
357
+ Option,
358
+ SelectWrapper,
359
+ SelectText,
360
+ Divider,
313
361
  },
314
362
  inheritAttrs: false,
315
363
  props: {
@@ -447,6 +495,22 @@
447
495
  required: false,
448
496
  default: '',
449
497
  },
498
+ showSelect: {
499
+ type: Boolean,
500
+ default: false,
501
+ },
502
+ selectWidth: {
503
+ type: Number,
504
+ default: 70,
505
+ },
506
+ selectOptions: {
507
+ type: Array,
508
+ default: () => [],
509
+ },
510
+ selectValue: {
511
+ type: [String, Number],
512
+ default: null,
513
+ },
450
514
  },
451
515
  data() {
452
516
  return {
@@ -468,6 +532,13 @@
468
532
  hasLabelSlot() {
469
533
  return !!this.$slots.label
470
534
  },
535
+ getSelectValue() {
536
+ const item = this.selectOptions.find(
537
+ ({ value }) => value === this.selectValue
538
+ )
539
+
540
+ return item ? item.label : '-'
541
+ },
471
542
  },
472
543
  watch: {
473
544
  focus(value) {
@@ -10,23 +10,31 @@
10
10
  :has-label="!!label && label.length > 0"
11
11
  :no-relative="noRelative"
12
12
  >
13
- <LabelWrapper v-if="label" :data-id="labelDataId">
13
+ <LabelWrapper
14
+ v-if="label"
15
+ :data-id="labelDataId"
16
+ :info-text-message="!!infoTextMessage"
17
+ >
14
18
  <InputLabel
15
19
  :font-color="
16
20
  labelFontColor || colorMode == 'dark' ? 'white' : 'eturnityGrey'
17
21
  "
18
22
  :font-size="fontSize"
19
- >
20
- {{ label }}
23
+ >{{ label }}
21
24
  <OptionalLabel v-if="labelOptional">
22
- ({{ $gettext('Optional') }})
23
- </OptionalLabel>
25
+ ({{ $gettext('Optional') }})</OptionalLabel
26
+ >
24
27
  </InputLabel>
25
28
  <InfoText
26
- v-if="infoTextMessage"
29
+ v-if="infoTextMessage || !!$slots.infoText"
30
+ :align-arrow="infoTextAlignArrow"
31
+ :max-width="infoTextWidth"
27
32
  :size="infoTextSize"
28
33
  :text="infoTextMessage"
29
- />
34
+ :width="infoTextWidth"
35
+ >
36
+ <slot name="infoText"></slot>
37
+ </InfoText>
30
38
  </LabelWrapper>
31
39
  <SelectButtonWrapper :disabled="disabled">
32
40
  <SelectButton
@@ -85,7 +93,7 @@
85
93
  <slot name="selector" :selected-value="selectedValue"></slot>
86
94
  </Selector>
87
95
  <Caret class="caret_dropdown" @click.stop="toggleCaretDropdown">
88
- <RCIcon
96
+ <Icon
89
97
  v-if="isDropdownOpen"
90
98
  :color="
91
99
  caretColor || colorMode == 'dark'
@@ -95,7 +103,7 @@
95
103
  name="arrow_up"
96
104
  size="12px"
97
105
  />
98
- <RCIcon
106
+ <Icon
99
107
  v-else
100
108
  :color="
101
109
  caretColor || colorMode == 'dark'
@@ -170,7 +178,7 @@
170
178
  import { Teleport } from 'vue'
171
179
  import styled from 'vue3-styled-components'
172
180
  import InfoText from '../../infoText'
173
- import RCIcon from '../../icon'
181
+ import Icon from '../../icon'
174
182
  import InputText from '../inputText'
175
183
  import DraggableInputHandle from '../../draggableInputHandle'
176
184
 
@@ -232,9 +240,12 @@
232
240
  position: ${(props) => (props.noRelative ? 'static' : 'relative')};
233
241
  display: inline-block;
234
242
  `
235
- const LabelWrapper = styled.div`
243
+
244
+ const LabelWrapperAttrs = { infoTextMessage: Boolean }
245
+ const LabelWrapper = styled('div', LabelWrapperAttrs)`
236
246
  display: inline-grid;
237
- grid-template-columns: auto auto;
247
+ grid-template-columns: ${(props) =>
248
+ props.infoTextMessage ? 'auto auto' : 'auto'};
238
249
  grid-gap: 12px;
239
250
  align-items: center;
240
251
  justify-content: start;
@@ -367,7 +378,7 @@
367
378
  }
368
379
  font-size: ${(props) => props.fontSize};
369
380
  `
370
- SelectDropdown.emits = ['option-hovered', 'option-selected']
381
+ selectDropdown.emits = ['option-hovered', 'option-selected']
371
382
  const DropdownAttrs = { noRelative: Boolean }
372
383
  const DropdownWrapper = styled('div', DropdownAttrs)`
373
384
  position: ${(props) => (props.noRelative ? 'static' : 'relative')};
@@ -411,7 +422,7 @@
411
422
  InfoText,
412
423
  InputWrapper,
413
424
  DropdownWrapper,
414
- RCIcon,
425
+ Icon,
415
426
  Caret,
416
427
  Selector,
417
428
  InputText,
@@ -542,6 +553,7 @@
542
553
  default: '',
543
554
  },
544
555
  hasSelectButtonPadding: {
556
+ required: false,
545
557
  type: Boolean,
546
558
  default: true,
547
559
  },
@@ -568,6 +580,14 @@
568
580
  type: String,
569
581
  default: DROPDOWN_MENU_POSITIONS.Automatic, // options: ['automatic', bottom]
570
582
  },
583
+ infoTextWidth: {
584
+ type: String,
585
+ required: false,
586
+ },
587
+ infoTextAlignArrow: {
588
+ type: String,
589
+ required: false,
590
+ },
571
591
  },
572
592
 
573
593
  data() {
@@ -31,7 +31,7 @@
31
31
  const TitleText = styled('span', titleAttrs)`
32
32
  color: ${(props) => (props.color ? props.color : props.theme.colors.black)};
33
33
  font-weight: bold;
34
- font-size: ${(props) => (props.fontSize ? props.fontSize : '18px')};
34
+ font-size: ${(props) => (props.fontSize ? props.fontSize : '20px')};
35
35
  text-transform: ${(props) => (props.uppercase ? 'uppercase' : 'none')};
36
36
  `
37
37
 
@@ -18,6 +18,8 @@
18
18
  v-else
19
19
  :cell-paddings="cellPaddings"
20
20
  :table-cursor="tableCursor"
21
+ @mouseleave="hasAimHover ? removeHoverClass() : null"
22
+ @mouseover="hasAimHover ? setHovers($event) : null"
21
23
  >
22
24
  <slot></slot>
23
25
  </TableContainer>
@@ -122,7 +124,8 @@
122
124
 
123
125
  tbody {
124
126
  tr {
125
- &:hover {
127
+ &:hover,
128
+ td.hovered-column {
126
129
  background-color: ${(props) => props.theme.colors.white};
127
130
  cursor: ${(props) =>
128
131
  props.tableCursor ? props.tableCursor : 'auto'};
@@ -410,6 +413,10 @@
410
413
  required: false,
411
414
  default: null,
412
415
  },
416
+ hasAimHover: {
417
+ required: false,
418
+ default: false,
419
+ },
413
420
  tableCursor: {
414
421
  required: false,
415
422
  },
@@ -423,12 +430,64 @@
423
430
  mounted() {
424
431
  this.observeTableHeight()
425
432
  },
426
- beforeDestroy() {
433
+ beforeUnmount() {
427
434
  if (this.resizeObserver) {
428
435
  this.resizeObserver.disconnect()
429
436
  }
430
437
  },
431
438
  methods: {
439
+ findParentElementByTagName(element, tagName) {
440
+ let currentParentElement = element.parentElement
441
+ while (
442
+ currentParentElement &&
443
+ currentParentElement.tagName !== tagName
444
+ ) {
445
+ currentParentElement = currentParentElement.parentElement
446
+ }
447
+
448
+ return currentParentElement && currentParentElement.tagName === tagName
449
+ ? currentParentElement
450
+ : null
451
+ },
452
+ removeHoverClass() {
453
+ const hoveredItems = document.querySelectorAll('.hovered-column')
454
+ hoveredItems.forEach((el) => {
455
+ el.classList.remove('hovered-column')
456
+ })
457
+ },
458
+ setHovers(event) {
459
+ this.removeHoverClass()
460
+ if (
461
+ event.target.tagName !== 'TABLE' &&
462
+ event.target.tagName !== 'TH' &&
463
+ event.target.tagName !== 'TR'
464
+ ) {
465
+ let hoveredCell = event.target
466
+
467
+ if (hoveredCell.tagName !== 'TD') {
468
+ // Looking for hovered TD element
469
+ hoveredCell = this.findParentElementByTagName(hoveredCell, 'TD')
470
+ }
471
+
472
+ if (hoveredCell) {
473
+ const rowChildren = Array.from(hoveredCell.parentElement.children)
474
+ const hoveredCellIndex = rowChildren.indexOf(hoveredCell)
475
+ const currentTable = this.findParentElementByTagName(
476
+ hoveredCell,
477
+ 'TABLE'
478
+ )
479
+ if (currentTable) {
480
+ const rowList = Array.from(currentTable.querySelectorAll('tr'))
481
+ rowList.forEach((el) => {
482
+ const cells = Array.from(el.children)
483
+ if (cells[hoveredCellIndex]) {
484
+ cells[hoveredCellIndex].classList.add('hovered-column')
485
+ }
486
+ })
487
+ }
488
+ }
489
+ }
490
+ },
432
491
  observeTableHeight() {
433
492
  if (!this.$refs.tableRef) return
434
493
 
@@ -0,0 +1,83 @@
1
+ <template>
2
+ <PageContainer>
3
+ <TabsContainer>
4
+ <TabItem
5
+ v-for="item in tabsData"
6
+ :key="item.id"
7
+ :is-active="activeTab === item.id"
8
+ @click="onTabClick({ id: item.id })"
9
+ >
10
+ {{ item.text }}
11
+ </TabItem>
12
+ </TabsContainer>
13
+ </PageContainer>
14
+ </template>
15
+
16
+ <script>
17
+ // import RCTabsHeader from "@eturnity/eturnity_reusable_components/src/components/tabsHeader"
18
+ // To use:
19
+ // <RCTabsHeader
20
+ // :activeTab="activeTabIndex" // should match the 'id'
21
+ // :tabsData="[
22
+ // {
23
+ // text: 'Tab 1',
24
+ // id: 0
25
+ // },
26
+ // {
27
+ // text: 'Tab 1',
28
+ // id: 1
29
+ // }
30
+ // ]"
31
+ // />
32
+ import styled from 'vue3-styled-components'
33
+
34
+ const PageContainer = styled.div``
35
+
36
+ const TabsContainer = styled.div`
37
+ display: flex;
38
+ cursor: pointer;
39
+ width: 100%;
40
+ `
41
+
42
+ const TabAttrs = { isActive: Boolean }
43
+ const TabItem = styled('div', TabAttrs)`
44
+ padding: 10px 20px;
45
+ font-size: 14px;
46
+ font-weight: 700;
47
+ background-color: ${(props) =>
48
+ props.isActive ? props.theme.colors.grey5 : props.theme.colors.white};
49
+ border-top: 3px solid
50
+ ${(props) =>
51
+ props.isActive
52
+ ? props.theme.colors.brightBlue
53
+ : props.theme.colors.grey4};
54
+ flex-grow: 1;
55
+ `
56
+
57
+ export default {
58
+ name: 'RCTabsHeader',
59
+ components: {
60
+ PageContainer,
61
+ TabsContainer,
62
+ TabItem
63
+ },
64
+ props: {
65
+ tabsData: {
66
+ required: true,
67
+ type: Array
68
+ },
69
+ activeTab: {
70
+ required: true,
71
+ type: Number
72
+ }
73
+ },
74
+ methods: {
75
+ onTabClick({ id }) {
76
+ if (id === this.activeTab) {
77
+ return
78
+ }
79
+ this.$emit('on-tab-change', id)
80
+ }
81
+ }
82
+ }
83
+ </script>