@eturnity/eturnity_reusable_components 8.7.5-EPIC-8593.2 → 8.7.5-EPIC-8593.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.
Files changed (108) hide show
  1. package/package.json +1 -1
  2. package/src/assets/icons/collapse_arrow_icon_white.svg +1 -0
  3. package/src/assets/svgIcons/ac_power.svg +4 -0
  4. package/src/assets/svgIcons/arrow_long_left.svg +3 -0
  5. package/src/assets/svgIcons/arrow_long_right.svg +3 -0
  6. package/src/assets/svgIcons/chassis_ground_symbol.svg +27 -0
  7. package/src/assets/svgIcons/dc_power.svg +8 -0
  8. package/src/assets/svgIcons/double_arrow_long.svg +4 -0
  9. package/src/assets/svgIcons/ed_ac.svg +3 -0
  10. package/src/assets/svgIcons/ed_acgrid.svg +4 -0
  11. package/src/assets/svgIcons/ed_arrow_both.svg +7 -0
  12. package/src/assets/svgIcons/ed_arrow_left.svg +7 -0
  13. package/src/assets/svgIcons/ed_arrow_right.svg +7 -0
  14. package/src/assets/svgIcons/ed_battery.svg +10 -0
  15. package/src/assets/svgIcons/ed_batteryacinverter.svg +16 -0
  16. package/src/assets/svgIcons/ed_batteryintegratedinverter.svg +19 -0
  17. package/src/assets/svgIcons/ed_cirquitbreaker.svg +4 -0
  18. package/src/assets/svgIcons/ed_cirquitbreaker_magnetic.svg +6 -0
  19. package/src/assets/svgIcons/ed_cirquitbreaker_thermal.svg +4 -0
  20. package/src/assets/svgIcons/ed_cirquitbreaker_thermal_magnetic.svg +5 -0
  21. package/src/assets/svgIcons/ed_consumption.svg +3 -0
  22. package/src/assets/svgIcons/ed_dc.svg +6 -0
  23. package/src/assets/svgIcons/ed_disconnector.svg +4 -0
  24. package/src/assets/svgIcons/ed_disconnector_fuse.svg +4 -0
  25. package/src/assets/svgIcons/ed_disconnector_fuse_switch.svg +4 -0
  26. package/src/assets/svgIcons/ed_disconnector_loadbreak switch.svg +4 -0
  27. package/src/assets/svgIcons/ed_disconnector_switch.svg +4 -0
  28. package/src/assets/svgIcons/ed_disconnector_switch_auto_release.svg +5 -0
  29. package/src/assets/svgIcons/ed_energymanagement_rectangle.svg +3 -0
  30. package/src/assets/svgIcons/ed_evcharger.svg +19 -0
  31. package/src/assets/svgIcons/ed_flexiblecomponent_circle.svg +3 -0
  32. package/src/assets/svgIcons/ed_flexiblecomponent_square.svg +3 -0
  33. package/src/assets/svgIcons/ed_fuse.svg +3 -0
  34. package/src/assets/svgIcons/ed_ground.svg +5 -0
  35. package/src/assets/svgIcons/ed_heatpump.svg +4 -0
  36. package/src/assets/svgIcons/ed_icon_battery.svg +9 -0
  37. package/src/assets/svgIcons/ed_icon_circle.svg +3 -0
  38. package/src/assets/svgIcons/ed_icon_heatpump.svg +3 -0
  39. package/src/assets/svgIcons/ed_icon_inverter.svg +8 -0
  40. package/src/assets/svgIcons/ed_icon_optimizer.svg +11 -0
  41. package/src/assets/svgIcons/ed_integratedbatteryinverter.svg +10 -0
  42. package/src/assets/svgIcons/ed_inverter-blank.svg +3 -0
  43. package/src/assets/svgIcons/ed_mainsconnection.svg +3 -0
  44. package/src/assets/svgIcons/ed_meter_arrowleft.svg +4 -0
  45. package/src/assets/svgIcons/ed_meter_arrowright.svg +4 -0
  46. package/src/assets/svgIcons/ed_meter_bidirectional.svg +5 -0
  47. package/src/assets/svgIcons/ed_networkandsystemprotection_double.svg +14 -0
  48. package/src/assets/svgIcons/ed_networkandsystemprotection_single.svg +7 -0
  49. package/src/assets/svgIcons/ed_pvpanel.svg +7 -0
  50. package/src/assets/svgIcons/ed_rcd.svg +5 -0
  51. package/src/assets/svgIcons/ed_rcd_simple.svg +3 -0
  52. package/src/assets/svgIcons/ed_spd.svg +6 -0
  53. package/src/assets/svgIcons/ed_stringwithoptimizer.svg +33 -0
  54. package/src/assets/svgIcons/ed_stringwithoutoptimizer.svg +17 -0
  55. package/src/assets/svgIcons/ed_transformer.svg +3 -0
  56. package/src/assets/svgIcons/ground_symbol.svg +28 -0
  57. package/src/assets/svgIcons/house_sun.svg +3 -0
  58. package/src/assets/svgIcons/move_left.svg +3 -0
  59. package/src/assets/svgIcons/move_right.svg +3 -0
  60. package/src/assets/svgIcons/rectangle.svg +3 -0
  61. package/src/assets/svgIcons/refresh.svg +3 -0
  62. package/src/assets/svgIcons/text_icon.svg +3 -0
  63. package/src/assets/theme.js +18 -1
  64. package/src/components/banner/infoBanner/InfoBanner.spec.js +29 -42
  65. package/src/components/barchart/BottomFields.vue +253 -0
  66. package/src/components/barchart/ChartControls.vue +113 -0
  67. package/src/components/barchart/SelectionBox.vue +150 -0
  68. package/src/components/barchart/composables/index.js +5 -0
  69. package/src/components/barchart/composables/useAxisCalculations.js +104 -0
  70. package/src/components/barchart/composables/useChartData.js +114 -0
  71. package/src/components/barchart/composables/useChartScroll.js +61 -0
  72. package/src/components/barchart/composables/useSelection.js +75 -0
  73. package/src/components/barchart/composables/useTooltip.js +100 -0
  74. package/src/components/barchart/index.vue +385 -0
  75. package/src/components/barchart/styles/bottomFields.js +66 -0
  76. package/src/components/barchart/styles/chart.js +272 -0
  77. package/src/components/barchart/styles/chartControls.js +59 -0
  78. package/src/components/buttons/buttonIcon/index.vue +5 -0
  79. package/src/components/buttons/splitButtons/index.vue +86 -0
  80. package/src/components/collapsableInfoText/index.vue +2 -2
  81. package/src/components/draggableCard/defaultProps.js +16 -0
  82. package/src/components/draggableCard/draggableCard.spec.js +99 -0
  83. package/src/components/draggableCard/draggableCard.stories.js +79 -0
  84. package/src/components/draggableCard/index.vue +363 -0
  85. package/src/components/errorMessage/errorMessage.spec.js +34 -0
  86. package/src/components/errorMessage/errorMessage.stories.js +35 -0
  87. package/src/components/filter/filterSettings.vue +2 -0
  88. package/src/components/icon/index.vue +32 -9
  89. package/src/components/infoText/index.vue +2 -2
  90. package/src/components/infoText/infoText.spec.js +6 -1
  91. package/src/components/inputs/checkbox/index.vue +2 -2
  92. package/src/components/inputs/inputNumber/index.vue +14 -2
  93. package/src/components/inputs/searchInput/index.vue +18 -2
  94. package/src/components/inputs/select/index.vue +104 -13
  95. package/src/components/modals/actionModal/actionModal.spec.js +52 -0
  96. package/src/components/modals/actionModal/actionModal.stories.js +53 -0
  97. package/src/components/modals/actionModal/index.vue +6 -6
  98. package/src/components/modals/infoModal/index.vue +49 -19
  99. package/src/components/modals/infoModal/infoModal.spec.js +55 -0
  100. package/src/components/modals/infoModal/infoModal.stories.js +47 -0
  101. package/src/components/modals/modal/index.vue +16 -5
  102. package/src/components/pageSubtitle/PageSubtitle.stories.js +0 -1
  103. package/src/components/spinnerGif/index.vue +3 -3
  104. package/src/components/tabsHeader/index.vue +29 -1
  105. package/src/helpers/dateTimeFormatting.js +51 -0
  106. package/src/helpers/isObjectEqual.js +22 -0
  107. package/src/helpers/toLocaleNumber.js +11 -0
  108. package/src/main.js +1 -0
@@ -1,6 +1,10 @@
1
1
  <template>
2
2
  <Container :input-width="inputWidth">
3
- <InputWrapper :icon-color="iconColor" :icon-position="iconPosition">
3
+ <InputWrapper
4
+ :icon-color="iconColor"
5
+ :icon-position="iconPosition"
6
+ :is-full-height="isFullHeight"
7
+ >
4
8
  <SearchIconSvg class="search-icn" />
5
9
  <InputContainer
6
10
  ref="inputElement"
@@ -11,6 +15,7 @@
11
15
  :input-width="inputWidth"
12
16
  :is-disabled="disabled"
13
17
  :is-filter="isFilter"
18
+ :is-full-height="isFullHeight"
14
19
  :placeholder="placeholder"
15
20
  :value="value"
16
21
  @input="onChangeHandler($event)"
@@ -41,6 +46,7 @@
41
46
  isDisabled: Boolean,
42
47
  inputWidth: String,
43
48
  isFilter: Boolean,
49
+ isFullHeight: Boolean,
44
50
  }
45
51
  const Container = styled('div', inputAttrs)`
46
52
  width: ${(props) => (props.inputWidth ? props.inputWidth : '100%')};
@@ -55,6 +61,7 @@
55
61
  font-size: 13px;
56
62
  color: ${(props) => props.theme.colors.black};
57
63
  width: ${(props) => (props.inputWidth ? props.inputWidth : '100%')};
64
+ height: ${(props) => (props.isFullHeight ? '100%' : 'auto')};
58
65
  box-sizing: border-box;
59
66
  cursor: ${(props) => (props.isDisabled ? 'not-allowed' : 'auto')};
60
67
  background: ${(props) => props.theme.colors.white} !important;
@@ -67,9 +74,14 @@
67
74
  }
68
75
  `
69
76
 
70
- const wrapperAttrs = { iconColor: String, iconPosition: String }
77
+ const wrapperAttrs = {
78
+ iconColor: String,
79
+ iconPosition: String,
80
+ isFullHeight: Boolean,
81
+ }
71
82
  const InputWrapper = styled('div', wrapperAttrs)`
72
83
  position: relative;
84
+ height: ${(props) => (props.isFullHeight ? '100%' : 'auto')};
73
85
 
74
86
  svg {
75
87
  position: absolute;
@@ -142,6 +154,10 @@
142
154
  type: String,
143
155
  default: 'black',
144
156
  },
157
+ isFullHeight: {
158
+ type: Boolean,
159
+ default: false,
160
+ },
145
161
  },
146
162
  emits: ['on-change'],
147
163
  watch: {
@@ -143,17 +143,19 @@
143
143
  </Caret>
144
144
  </SelectButton>
145
145
  <DropdownWrapper ref="dropdownWrapperRef" :no-relative="noRelative">
146
- <Teleport to="body">
146
+ <component
147
+ :is="shouldUseTeleport ? 'Teleport' : 'div'"
148
+ :to="shouldUseTeleport ? 'body' : undefined"
149
+ >
147
150
  <SelectDropdown
148
151
  v-show="isSelectDropdownShown"
149
152
  ref="dropdown"
150
153
  :bg-color="
151
- dropdownBgColor ||
152
- colorMode == 'dark' ||
153
- colorMode == 'transparent'
154
+ colorMode == 'dark' || colorMode == 'transparent'
154
155
  ? 'black'
155
156
  : 'white'
156
157
  "
158
+ class="rc-select-dropdown"
157
159
  :dropdown-position="dropdownPosition"
158
160
  :font-color="
159
161
  dropdownFontColor ||
@@ -173,17 +175,29 @@
173
175
  :hovered-index="hoveredIndex"
174
176
  :hovered-value="hoveredValue"
175
177
  :is-active="isActive"
178
+ :is-fixed-dropdown-position="isFixedDropdownPosition"
179
+ :is-parent-modal="isParentModal"
180
+ :is-teleport="shouldUseTeleport"
176
181
  :min-width="minWidth"
177
182
  :no-relative="noRelative"
178
183
  :option-width="getOptionWidth"
179
184
  :selected-value="selectedValue"
185
+ :style="
186
+ shouldUseTeleport
187
+ ? {
188
+ transform: `translate(${dropdownPosition?.left}px, ${
189
+ noRelative ? 'auto' : `${dropdownPosition?.top}px`
190
+ })`,
191
+ }
192
+ : undefined
193
+ "
180
194
  @mouseleave="optionLeave"
181
195
  @option-hovered="optionHovered"
182
196
  @option-selected="optionSelected"
183
197
  >
184
198
  <slot name="dropdown"></slot>
185
199
  </SelectDropdown>
186
- </Teleport>
200
+ </component>
187
201
  </DropdownWrapper>
188
202
  </SelectButtonWrapper>
189
203
  </InputWrapper>
@@ -214,7 +228,7 @@
214
228
  // </template>
215
229
  // </Select>
216
230
 
217
- import { Teleport } from 'vue'
231
+ import { Teleport, inject } from 'vue'
218
232
  import styled from 'vue3-styled-components'
219
233
  import InfoText from '../../infoText'
220
234
  import Icon from '../../icon'
@@ -401,14 +415,18 @@
401
415
  selectedValue: Number | String,
402
416
  noRelative: Boolean,
403
417
  minWidth: String,
418
+ isParentModal: Boolean,
419
+ isFixedDropdownPosition: Boolean,
420
+ isTeleport: Boolean,
404
421
  }
405
422
  const SelectDropdown = styled('div', selectDropdownAttrs)`
406
423
  box-sizing: border-box;
407
- z-index: ${(props) => (props.isActive ? '2' : '99999')};
408
- position: absolute;
409
- top: ${(props) =>
410
- props.noRelative ? 'auto' : props.dropdownPosition?.top + 'px'};
411
- left: ${(props) => props.dropdownPosition?.left}px;
424
+ z-index: ${(props) =>
425
+ props.isActive ? '2' : props.isParentModal ? '9999999' : '99999'};
426
+ position: ${(props) =>
427
+ props.isFixedDropdownPosition ? 'fixed' : 'absolute'};
428
+ top: ${(props) => (props.isTeleport ? '0px' : '4px')};
429
+ left: 0px;
412
430
  border: ${BORDER_WIDTH} solid ${(props) => props.theme.colors.grey4};
413
431
  border-radius: 4px;
414
432
  display: flex;
@@ -667,6 +685,23 @@
667
685
  required: false,
668
686
  default: false,
669
687
  },
688
+ isFixedDropdownPosition: {
689
+ type: Boolean,
690
+ required: false,
691
+ default: false,
692
+ },
693
+ shouldUseTeleport: {
694
+ type: Boolean,
695
+ required: false,
696
+ default: true,
697
+ },
698
+ },
699
+ setup() {
700
+ const modalRef = inject('modalRef')
701
+
702
+ return {
703
+ modalRef,
704
+ }
670
705
  },
671
706
 
672
707
  data() {
@@ -684,6 +719,10 @@
684
719
  },
685
720
  dropdownWidth: null,
686
721
  hoveredValue: null,
722
+ isDisplayedAtBottom: true,
723
+ selectTopPosition: 0,
724
+ selectAndDropdownDistance: 0,
725
+ animationFrameId: null,
687
726
  }
688
727
  },
689
728
  computed: {
@@ -741,6 +780,9 @@
741
780
  /windows phone/i.test(userAgent)
742
781
  )
743
782
  },
783
+ isParentModal() {
784
+ return !!this.modalRef
785
+ },
744
786
  },
745
787
  watch: {
746
788
  value(val) {
@@ -754,8 +796,13 @@
754
796
  }, 10)
755
797
  await this.$nextTick()
756
798
  this.handleSetDropdownOffet()
799
+ if (!this.isFixedDropdownPosition) this.calculateSelectTopPosition()
757
800
  } else {
758
801
  this.dropdownPosition.left = null
802
+ if (this.animationFrameId) {
803
+ cancelAnimationFrame(this.animationFrameId)
804
+ this.animationFrameId = null
805
+ }
759
806
  setTimeout(() => {
760
807
  this.isClickOutsideActive = false
761
808
  }, 10)
@@ -768,11 +815,30 @@
768
815
  })
769
816
  }
770
817
  },
818
+ isSelectDropdownShown(isShown) {
819
+ if (!isShown) return
820
+ // Need to wait for 1ms to make sure the dropdown menu is shown in the DOM
821
+ // before getting the distance between the select and the dropdown menu
822
+ setTimeout(() => {
823
+ this.getDistanceBetweenSelectAndDropdownMenu()
824
+ }, 100)
825
+ },
826
+ selectTopPosition() {
827
+ this.dropdownPosition.top =
828
+ this.selectTopPosition +
829
+ this.$refs.select.$el.clientHeight +
830
+ this.selectAndDropdownDistance
831
+ },
771
832
  },
772
833
  mounted() {
773
834
  this.observeDropdownHeight()
774
835
  this.observeSelectWidth()
775
836
  window.addEventListener('resize', this.handleSetDropdownOffet)
837
+ if (!this.isFixedDropdownPosition)
838
+ document.body.addEventListener(
839
+ 'scroll',
840
+ this.calculateSelectTopPosition
841
+ )
776
842
  },
777
843
  beforeMount() {
778
844
  this.selectedValue = this.value
@@ -781,6 +847,12 @@
781
847
  window.removeEventListener('resize', this.handleSetDropdownOffet)
782
848
  if (this.dropdownResizeObserver) this.dropdownResizeObserver.disconnect()
783
849
  if (this.selectResizeObserver) this.selectResizeObserver.disconnect()
850
+ if (!this.isFixedDropdownPosition) {
851
+ document.body.removeEventListener(
852
+ 'scroll',
853
+ this.calculateSelectTopPosition
854
+ )
855
+ }
784
856
  },
785
857
  unmounted() {
786
858
  document.removeEventListener('click', this.clickOutside)
@@ -886,11 +958,11 @@
886
958
  return
887
959
  }
888
960
  await this.$nextTick()
889
- const isDisplayedAtBottom = await this.generateDropdownPosition()
961
+ this.isDisplayedAtBottom = await this.generateDropdownPosition()
890
962
  // If the dropdown menu is going to be displayed at the bottom,
891
963
  // we need reverify its position after a dom update (nextTick)
892
964
  await this.$nextTick()
893
- if (isDisplayedAtBottom) this.generateDropdownPosition()
965
+ if (this.isDisplayedAtBottom) this.generateDropdownPosition()
894
966
  },
895
967
  async generateDropdownPosition() {
896
968
  const isDropdownNotCompletelyVisible =
@@ -983,6 +1055,25 @@
983
1055
  }
984
1056
  }
985
1057
  },
1058
+ getDistanceBetweenSelectAndDropdownMenu() {
1059
+ const wholeSelectTopPosition =
1060
+ this.selectTopPosition + this.$refs.select.$el.clientHeight
1061
+ this.selectAndDropdownDistance =
1062
+ this.dropdownPosition.top - wholeSelectTopPosition
1063
+ },
1064
+ calculateSelectTopPosition() {
1065
+ const selectRef = this.$refs.select
1066
+ if (selectRef) {
1067
+ const currentTopPosition =
1068
+ selectRef.$el.getBoundingClientRect().top + window.scrollY
1069
+ if (this.selectTopPosition !== currentTopPosition) {
1070
+ this.selectTopPosition = currentTopPosition
1071
+ }
1072
+ }
1073
+ this.animationFrameId = requestAnimationFrame(
1074
+ this.calculateSelectTopPosition
1075
+ )
1076
+ },
986
1077
  },
987
1078
  }
988
1079
  </script>
@@ -0,0 +1,52 @@
1
+ /* eslint-disable */
2
+ import { mount } from '@vue/test-utils'
3
+ import ActionModal from '@/components/modals/actionModal'
4
+ import theme from '@/assets/theme'
5
+
6
+ describe('ActionModal Component', () => {
7
+ let wrapper
8
+
9
+ beforeEach(() => {
10
+ wrapper = mount(ActionModal, {
11
+ props: {
12
+ isOpen: true,
13
+ buttonText: 'Close',
14
+ },
15
+ slots: {
16
+ title: 'Sample title',
17
+ body: 'Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed tincidunt commodo mollis. Fusce urna felis, malesuada sed elementum et, fermentum ac massa. Integer in massa vel orci fermentum bibendum in ut ante. Donec risus risus, luctus quis ex a, pulvinar placerat lacus. Sed pharetra augue a elit volutpat, eu dignissim ex pretium. Aenean imperdiet, nulla in pharetra rutrum, mauris mauris tincidunt tellus, non tempus quam lorem laoreet lectus.',
18
+ buttons: '<button @click="closeAction">Close</button>',
19
+ },
20
+ global: {
21
+ provide: {
22
+ theme,
23
+ },
24
+ },
25
+ })
26
+ })
27
+
28
+ test('renders ActionModal component with default props', () => {
29
+ expect(wrapper.find('[data-test-id="actionModal"]').exists()).toBe(true)
30
+
31
+ expect(wrapper.vm.isOpen).toBe(true)
32
+ })
33
+
34
+ test('action modal slots is display when user passed slots content', () => {
35
+ const modalTitleEl = wrapper.find('[data-test-id="modal_title"]')
36
+ expect(modalTitleEl.text()).toBe('Sample title')
37
+
38
+ const modalBodyEl = wrapper.find('[data-test-id="modal_body"]')
39
+ expect(modalBodyEl.text()).toContain('Lorem ipsum dolor sit amet')
40
+
41
+ const modalActionButton = wrapper.find('[data-test-id="modal_buttons"]')
42
+ expect(modalActionButton.text()).toContain('Close')
43
+ })
44
+
45
+ test('action modal on-close event is emitted when modal close button is clicked', async () => {
46
+ const modalCloseButton = wrapper.find('.close')
47
+
48
+ modalCloseButton.trigger('click')
49
+ await wrapper.vm.$nextTick()
50
+ expect(wrapper.emitted('on-close')).toBeTruthy()
51
+ })
52
+ })
@@ -0,0 +1,53 @@
1
+ import ActionModal from './index.vue'
2
+
3
+ export default {
4
+ title: 'Components/ActionModal',
5
+ component: ActionModal,
6
+ tags: ['autodocs'],
7
+ parameters: {
8
+ layout: 'centered',
9
+ },
10
+ }
11
+
12
+ // import ActionModal from "@eturnity/eturnity_reusable_components/src/components/modals/ActionModal"
13
+ // This is a reusable modal component that can be used to display information to the user.
14
+ // To use:
15
+ // <ActionModal :isOpen="isOpen" @on-close="$emit('on-close-summary')" >
16
+ // <template #title>
17
+ // <h1>Header</h1>
18
+ // </template>
19
+ // <template #body>
20
+ // <p>Body</p>
21
+ // </template>
22
+ // <template #buttons>
23
+ // <button @click="closeModal">Close</button>
24
+ // </template>
25
+ // </ActionModal>
26
+
27
+ export const Default = {
28
+ args: {
29
+ isOpen: true,
30
+ },
31
+ render: (args) => ({
32
+ components: { ActionModal },
33
+ setup() {
34
+ return { args }
35
+ },
36
+ template: `
37
+ <ActionModal v-bind="args">
38
+ <template #title>Sample title</template>
39
+ <template #body>
40
+ Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed tincidunt commodo mollis. Fusce urna felis,
41
+ malesuada sed elementum et, fermentum ac massa. Integer in massa vel orci fermentum bibendum in ut ante.
42
+ Donec risus risus, luctus quis ex a, pulvinar placerat lacus. Sed pharetra augue a elit volutpat, eu dignissim
43
+ ex pretium. Aenean imperdiet, nulla in pharetra rutrum, mauris mauris tincidunt tellus, non tempus quam lorem
44
+ laoreet lectus.
45
+ </template>
46
+ <template #buttons>
47
+ <button @click="saveAction">Save</button>
48
+ <button @click="closeAction">Close</button>
49
+ </template>
50
+ </ActionModal>
51
+ `,
52
+ }),
53
+ }
@@ -1,13 +1,13 @@
1
1
  <template>
2
- <Modal :is-open="isOpen" @on-close="closeModal">
2
+ <Modal data-test-id="actionModal" :is-open="isOpen" @on-close="closeModal">
3
3
  <ModalContainer>
4
- <ModalTitle v-if="$slots.title">
4
+ <ModalTitle v-if="$slots.title" data-test-id="modal_title">
5
5
  <slot name="title"></slot>
6
6
  </ModalTitle>
7
- <TextContainer v-if="$slots.body">
7
+ <TextContainer v-if="$slots.body" data-test-id="modal_body">
8
8
  <slot name="body"></slot>
9
9
  </TextContainer>
10
- <ButtonContainer v-if="$slots.buttons">
10
+ <ButtonContainer v-if="$slots.buttons" data-test-id="modal_buttons">
11
11
  <slot name="buttons"></slot>
12
12
  </ButtonContainer>
13
13
  </ModalContainer>
@@ -23,7 +23,7 @@
23
23
  `
24
24
  const ModalTitle = styled.div`
25
25
  color: ${(props) => props.theme.colors.black};
26
- font-family: ${(props) => props.theme.fonts.mainFont};
26
+ font-family: inherit;
27
27
  font-size: 18px;
28
28
  font-style: normal;
29
29
  font-weight: 700;
@@ -37,7 +37,7 @@
37
37
  `
38
38
  const TextContainer = styled.div`
39
39
  color: ${(props) => props.theme.colors.black};
40
- font-family: ${(props) => props.theme.fonts.mainFont};
40
+ font-family: inherit;
41
41
  font-size: 13px;
42
42
  font-style: normal;
43
43
  font-weight: 400;
@@ -1,48 +1,78 @@
1
1
  <template>
2
- <ActionModal :is-open="isOpen" @on-close="closeModal">
2
+ <RCModal data-test-id="infoModal" :is-open="isOpen" @on-close="closeModal">
3
3
  <ModalContainer>
4
- <template #title>
4
+ <ModalTitle v-if="$slots.title" data-test-id="modal_title">
5
5
  <slot name="title"></slot>
6
- </template>
7
- <template #body>
6
+ </ModalTitle>
7
+ <TextContainer v-if="$slots.body" data-test-id="modal_body">
8
8
  <slot name="body"></slot>
9
- </template>
10
- <template #buttons>
11
- <ButtonContainer>
12
- <RCMainButton
13
- min-width="150px"
14
- :text="$gettext('Got it')"
15
- type="primary"
16
- @click="closeModal"
17
- />
18
- </ButtonContainer>
19
- </template>
9
+ </TextContainer>
10
+ <ButtonContainer>
11
+ <RCMainButton
12
+ min-width="150px"
13
+ :text="buttonText"
14
+ type="primary"
15
+ @click="closeModal"
16
+ />
17
+ </ButtonContainer>
20
18
  </ModalContainer>
21
- </ActionModal>
19
+ </RCModal>
22
20
  </template>
23
21
  <script>
24
22
  import styled from 'vue3-styled-components'
25
- import ActionModal from '../actionModal'
23
+ import RCModal from '../modal'
26
24
  import RCMainButton from '../../buttons/mainButton'
25
+
27
26
  const ModalContainer = styled.div`
28
27
  width: 450px;
29
28
  min-height: 205px;
30
29
  padding: 40px 40px 30px 40px;
31
30
  `
31
+ const ModalTitle = styled.div`
32
+ color: ${(props) => props.theme.colors.black};
33
+ font-family: inherit;
34
+ font-size: 18px;
35
+ font-style: normal;
36
+ font-weight: 700;
37
+ line-height: 120%;
38
+ text-transform: uppercase;
39
+ `
32
40
  const ButtonContainer = styled.div`
33
41
  display: inline-flex;
34
42
  align-items: flex-start;
35
43
  gap: 20px;
36
44
  `
45
+ const TextContainer = styled.div`
46
+ color: ${(props) => props.theme.colors.black};
47
+ font-family: inherit;
48
+ font-size: 13px;
49
+ font-style: normal;
50
+ font-weight: 400;
51
+ line-height: normal;
52
+ padding: 30px 0px;
53
+ white-space: pre-wrap;
54
+ `
55
+
37
56
  export default {
38
57
  name: 'InfoModal',
39
58
  components: {
59
+ RCModal,
40
60
  ModalContainer,
61
+ ModalTitle,
41
62
  ButtonContainer,
42
- ActionModal,
63
+ TextContainer,
43
64
  RCMainButton,
44
65
  },
45
- props: ['isOpen'],
66
+ props: {
67
+ isOpen: {
68
+ type: Boolean,
69
+ required: true,
70
+ },
71
+ buttonText: {
72
+ type: String,
73
+ default: 'Got it',
74
+ },
75
+ },
46
76
  methods: {
47
77
  closeModal() {
48
78
  this.$emit('on-close')
@@ -0,0 +1,55 @@
1
+ /* eslint-disable */
2
+ import { mount } from '@vue/test-utils'
3
+ import InfoModal from '@/components/modals/infoModal'
4
+ import theme from '@/assets/theme'
5
+
6
+ jest.mock('@/components/icon/iconCache.mjs', () => ({
7
+ // need to mock this due to how jest handles import.meta
8
+ fetchIcon: jest.fn(() => Promise.resolve('')),
9
+ }))
10
+
11
+
12
+ describe('InfoModal Component', () => {
13
+ let wrapper
14
+
15
+ beforeEach(() => {
16
+ wrapper = mount(InfoModal, {
17
+ props: {
18
+ isOpen: true,
19
+ buttonText: 'Close',
20
+ },
21
+ slots: {
22
+ title: 'Sample title',
23
+ body: 'Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed tincidunt commodo mollis. Fusce urna felis, malesuada sed elementum et, fermentum ac massa. Integer in massa vel orci fermentum bibendum in ut ante. Donec risus risus, luctus quis ex a, pulvinar placerat lacus. Sed pharetra augue a elit volutpat, eu dignissim ex pretium. Aenean imperdiet, nulla in pharetra rutrum, mauris mauris tincidunt tellus, non tempus quam lorem laoreet lectus.',
24
+ },
25
+ global: {
26
+ provide: {
27
+ theme,
28
+ },
29
+ },
30
+ })
31
+ })
32
+
33
+ test('renders InfoModal component with default props', () => {
34
+ expect(wrapper.find('[data-test-id="infoModal"]').exists()).toBe(true)
35
+
36
+ expect(wrapper.vm.isOpen).toBe(true)
37
+ expect(wrapper.vm.buttonText).toContain('Close')
38
+ })
39
+
40
+ test('info modal slots is display when user passed slots content', () => {
41
+ const modalTitleEl = wrapper.find('[data-test-id="modal_title"]')
42
+ expect(modalTitleEl.text()).toBe('Sample title')
43
+
44
+ const modalBodyEl = wrapper.find('[data-test-id="modal_body"]')
45
+ expect(modalBodyEl.text()).toContain('Lorem ipsum dolor sit amet')
46
+ })
47
+
48
+ test('info modal on-close event is emitted when modal close button is clicked', async () => {
49
+ const modalCloseButton = wrapper.find('.close')
50
+
51
+ modalCloseButton.trigger('click')
52
+ await wrapper.vm.$nextTick()
53
+ expect(wrapper.emitted('on-close')).toBeTruthy()
54
+ })
55
+ })
@@ -0,0 +1,47 @@
1
+ import InfoModal from './index.vue'
2
+
3
+ export default {
4
+ title: 'Components/InfoModal',
5
+ component: InfoModal,
6
+ tags: ['autodocs'],
7
+ parameters: {
8
+ layout: 'centered',
9
+ },
10
+ }
11
+
12
+ // import InfoModal from "@eturnity/eturnity_reusable_components/src/components/modals/infoModal"
13
+ // This is a reusable modal component that can be used to display information to the user.
14
+ // To use:
15
+ // <InfoModal :isOpen="isOpen" @on-close="$emit('on-close-summary')" >
16
+ // <template #title>
17
+ // <h1>Header</h1>
18
+ // </template>
19
+ // <template #body>
20
+ // <p>Body</p>
21
+ // </template>
22
+ // </InfoModal>
23
+
24
+ export const Default = {
25
+ args: {
26
+ isOpen: true,
27
+ buttonText: 'Close',
28
+ },
29
+ render: (args) => ({
30
+ components: { InfoModal },
31
+ setup() {
32
+ return { args }
33
+ },
34
+ template: `
35
+ <InfoModal v-bind="args">
36
+ <template #title>Sample title</template>
37
+ <template #body>
38
+ Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed tincidunt commodo mollis. Fusce urna felis,
39
+ malesuada sed elementum et, fermentum ac massa. Integer in massa vel orci fermentum bibendum in ut ante.
40
+ Donec risus risus, luctus quis ex a, pulvinar placerat lacus. Sed pharetra augue a elit volutpat, eu dignissim
41
+ ex pretium. Aenean imperdiet, nulla in pharetra rutrum, mauris mauris tincidunt tellus, non tempus quam lorem
42
+ laoreet lectus.
43
+ </template>
44
+ </InfoModal>
45
+ `,
46
+ }),
47
+ }
@@ -1,8 +1,10 @@
1
1
  <template>
2
2
  <PageWrapper
3
3
  v-if="isOpen"
4
+ ref="modalRef"
4
5
  :add-padding-top="addPaddingTop"
5
6
  :backdrop="backdrop"
7
+ class="rc-modal-wrapper"
6
8
  :is-open="isOpen"
7
9
  :position="position"
8
10
  >
@@ -36,6 +38,7 @@
36
38
  // <div>Data....</div>
37
39
  // </modal>
38
40
 
41
+ import { ref, provide } from 'vue'
39
42
  import styled from 'vue3-styled-components'
40
43
  import CloseButton from '../../buttons/closeButton'
41
44
  import Spinner from '../../spinner'
@@ -58,14 +61,14 @@
58
61
  props.backdrop == 'dark'
59
62
  ? 'rgba(0, 0, 0, 0.4)'
60
63
  : 'rgba(255, 255, 255, 0.9)'};
61
- z-index: 99999;
64
+ z-index: 9999999;
62
65
  overflow: auto;
63
66
  padding-top: ${(props) => (props.addPaddingTop ? '80px' : '0')};
64
67
 
65
- @media (max-width: 425px) {
66
- background: white;
67
- }
68
- `
68
+ @media (max-width: 425px) {
69
+ background: white;
70
+ }
71
+ `
69
72
 
70
73
  const modalContainerAttrs = { overflow: String, isLoading: Boolean }
71
74
  const ModalContainer = styled('div', modalContainerAttrs)`
@@ -163,6 +166,14 @@
163
166
  default: false,
164
167
  },
165
168
  },
169
+ setup() {
170
+ const modalRef = ref(null)
171
+ provide('modalRef', modalRef)
172
+
173
+ return {
174
+ modalRef,
175
+ }
176
+ },
166
177
  watch: {
167
178
  isOpen: {
168
179
  immediate: true,