@eturnity/eturnity_reusable_components 8.22.1 → 8.22.2

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": "8.22.1",
3
+ "version": "8.22.2",
4
4
  "files": [
5
5
  "dist",
6
6
  "src"
@@ -0,0 +1,16 @@
1
+ export default {
2
+ text: 'default text',
3
+ size: '14px',
4
+ infoPosition: 'bottom',
5
+ alignArrow: 'center',
6
+ openTrigger: 'onHover',
7
+ width: '165px',
8
+ maxWidth: '165px',
9
+ shouldUseTeleport: false,
10
+ dotColor: '#00009f',
11
+ type: 'info',
12
+ iconTextContent: {
13
+ iconName: 'error',
14
+ text: 'Sample Text',
15
+ },
16
+ }
@@ -1,6 +1,7 @@
1
1
  <template>
2
2
  <PageContainer
3
3
  ref="container"
4
+ data-test-id="infoText_container"
4
5
  :type="type"
5
6
  @click=";(isMobile || openTrigger === 'onClick') && toggleInfo()"
6
7
  @mouseenter="!isMobile && openTrigger === 'onHover' && showInfo()"
@@ -287,6 +288,11 @@
287
288
  default: '',
288
289
  required: false,
289
290
  },
291
+ contentBackgroundColor: {
292
+ type: String,
293
+ default: '',
294
+ required: false,
295
+ },
290
296
  borderRadius: {
291
297
  type: String,
292
298
  default: '',
@@ -466,7 +472,9 @@
466
472
  width: '100%',
467
473
  maxWidth: props.maxWidth,
468
474
  overflowY: 'auto',
469
- backgroundColor: props.image
475
+ backgroundColor: props.contentBackgroundColor
476
+ ? props.contentBackgroundColor
477
+ : props.image
470
478
  ? theme.colors.white
471
479
  : props.appTheme === 'light'
472
480
  ? theme.colors.black
@@ -1,7 +1,8 @@
1
1
  /* eslint-disable */
2
2
  import { mount } from '@vue/test-utils'
3
3
  import InfoText from '@/components/infoText'
4
- import theme from '@/assets/theme'
4
+ import defaultProps from './defaultProps'
5
+ import IconTextContent from './templates/iconTextContent.vue'
5
6
 
6
7
  jest.mock('@/components/icon/iconCache.mjs', () => ({
7
8
  // need to mock this due to how jest handles import.meta
@@ -13,31 +14,19 @@ describe('InfoText Component', () => {
13
14
 
14
15
  beforeEach(() => {
15
16
  wrapper = mount(InfoText, {
16
- props: {
17
- text: 'default text',
18
- size: '14px',
19
- infoPosition: 'bottom',
20
- alignArrow: 'center',
21
- openTrigger: 'onHover',
22
- width: '165px',
23
- maxWidth: '165px',
24
- shouldUseTeleport: false,
25
- dotColor: '#00009f',
26
- type: 'info',
27
- },
17
+ props: defaultProps,
28
18
  global: {
29
- provide: {
30
- theme,
31
- },
32
19
  stubs: {
33
- teleport: true
34
- }
20
+ teleport: true,
21
+ },
35
22
  },
36
23
  })
37
24
  })
38
25
 
39
26
  test('renders InfoText component with default props', () => {
40
- expect(wrapper.find('[data-test-id="infoText_info"]').exists()).toBe(true)
27
+ expect(wrapper.find('[data-test-id="infoText_container"]').exists()).toBe(
28
+ true
29
+ )
41
30
  expect(wrapper.vm.text).toContain('default text')
42
31
  expect(wrapper.vm.size).toContain('14px')
43
32
  expect(wrapper.vm.infoPosition).toContain('bottom')
@@ -52,7 +41,7 @@ describe('InfoText Component', () => {
52
41
  )
53
42
 
54
43
  //should see text upon click
55
- await wrapper.find('[data-test-id="infoText_trigger"]').trigger('click')
44
+ await wrapper.trigger('click')
56
45
  expect(wrapper.vm.isVisible).toBe(true)
57
46
 
58
47
  expect(wrapper.find('[data-test-id="info_text_wrapper"]').exists()).toBe(
@@ -64,4 +53,34 @@ describe('InfoText Component', () => {
64
53
  await wrapper.setProps({ type: 'dot' })
65
54
  expect(wrapper.find('[data-test-id="infoText_dot"]').exists()).toBe(true)
66
55
  })
56
+
57
+ test('iconTextContent slot is correctly rendered', async () => {
58
+ // override
59
+ const props = defaultProps.iconTextContent
60
+ wrapper = mount(InfoText, {
61
+ props: defaultProps,
62
+ slots: {
63
+ default: `<IconTextContent icon-name="${props.iconName}" text="${props.text}" />`,
64
+ },
65
+ global: {
66
+ stubs: {
67
+ teleport: true,
68
+ },
69
+ components: {
70
+ IconTextContent,
71
+ },
72
+ },
73
+ })
74
+
75
+ await wrapper.trigger('mouseenter')
76
+ expect(wrapper.vm.isVisible).toBe(true)
77
+
78
+ const container = wrapper.find('[data-test-id="iconTextContent_container"]')
79
+ const icon = container.find('[data-test-id="iconTextContent_icon"]')
80
+ const text = container.find('[data-test-id="iconTextContent_text"]')
81
+ expect(container.exists()).toBe(true)
82
+ expect(icon.exists()).toBe(true)
83
+ expect(text.exists()).toBe(true)
84
+ expect(text.text()).toBe(props.text)
85
+ })
67
86
  })
@@ -1,4 +1,6 @@
1
+ import theme from '../../assets/theme'
1
2
  import InfoText from './index.vue'
3
+ import IconTextContent from './templates/iconTextContent.vue'
2
4
 
3
5
  export default {
4
6
  title: 'infoText',
@@ -46,3 +48,29 @@ export const OnClick = {
46
48
  openTrigger: 'onClick',
47
49
  },
48
50
  }
51
+
52
+ export const IconTextContentTemplate = {
53
+ args: {
54
+ ...Default.args,
55
+ contentBackgroundColor: 'black',
56
+ iconName: 'warning_triangle',
57
+ iconColor: theme.colors.yellow,
58
+ size: '18px',
59
+ },
60
+ render: (args) => ({
61
+ components: { InfoText, IconTextContent },
62
+ setup() {
63
+ return { args }
64
+ },
65
+ template: `
66
+ <InfoText v-bind="args">
67
+ <IconTextContent
68
+ icon-name="warning_triangle"
69
+ text="This is a sample text with an icon"
70
+ icon-size="${args.size}"
71
+ icon-color="${args.iconColor}"
72
+ />
73
+ </InfoText>
74
+ `,
75
+ }),
76
+ }
@@ -0,0 +1,105 @@
1
+ <template>
2
+ <Container data-test-id="iconTextContent_container">
3
+ <RCIcon
4
+ :color="iconColor"
5
+ data-test-id="iconTextContent_icon"
6
+ :name="iconName"
7
+ :size="iconSize"
8
+ />
9
+ <TextWrapper
10
+ data-test-id="iconTextContent_text"
11
+ :font-color="fontColor"
12
+ :font-size="fontSize"
13
+ >
14
+ {{ text }}
15
+ <slot data-test-id="iconTextContent_slot"></slot>
16
+ </TextWrapper>
17
+ </Container>
18
+ </template>
19
+
20
+ <script>
21
+ // import InfoText from "@eturnity/eturnity_reusable_components/src/components/infoText"
22
+ // import IconTextContent from "@eturnity/eturnity_reusable_components/src/components/infoText/templates/iconTextContent"
23
+ //To use:
24
+ // <InfoText
25
+ // icon-color="red"
26
+ // icon-name="error"
27
+ // size="20px"
28
+ // open-trigger="onClick"
29
+ // >
30
+ // <IconTextContent
31
+ // icon-name="error"
32
+ // text="Text"
33
+ // icon-size="18px"
34
+ // icon-color="red"
35
+ // />
36
+ // </InfoText>
37
+
38
+ import styled from 'vue3-styled-components'
39
+ import theme from '../../../assets/theme.js'
40
+ import RCIcon from '../../icon'
41
+
42
+ const Container = styled('div')`
43
+ display: flex;
44
+ flex-direction: row;
45
+ align-items: flex-start;
46
+ gap: 8px;
47
+ `
48
+
49
+ const TextAttrs = {
50
+ fontSize: String,
51
+ fontColor: String,
52
+ }
53
+ const TextWrapper = styled('div', TextAttrs)`
54
+ font-size: ${(props) => props.fontSize};
55
+ color: ${(props) => props.fontColor};
56
+ overflow: hidden;
57
+ display: flex;
58
+ flex-direction: column;
59
+ align-items: center;
60
+ gap: 8px;
61
+ font-weight: 400;
62
+ line-height: 150%;
63
+ letter-spacing: 0%;
64
+ vertical-align: middle;
65
+ `
66
+
67
+ export default {
68
+ name: 'IconTextContent',
69
+ components: {
70
+ Container,
71
+ TextWrapper,
72
+ RCIcon,
73
+ },
74
+ props: {
75
+ iconName: {
76
+ type: String,
77
+ required: true,
78
+ },
79
+ text: {
80
+ type: String,
81
+ required: true,
82
+ },
83
+ iconSize: {
84
+ type: String,
85
+ required: false,
86
+ default: '18px',
87
+ },
88
+ iconColor: {
89
+ type: String,
90
+ required: false,
91
+ default: '',
92
+ },
93
+ fontSize: {
94
+ type: String,
95
+ required: false,
96
+ default: '11px',
97
+ },
98
+ fontColor: {
99
+ type: String,
100
+ required: false,
101
+ default: theme.colors.white,
102
+ },
103
+ },
104
+ }
105
+ </script>
@@ -1,6 +1,8 @@
1
1
  <template>
2
2
  <SpinnerContainer
3
3
  v-if="fullWidth"
4
+ data-id="spinner_full_container"
5
+ data-qa-id="spinner_full_container"
4
6
  data-test-id="spinner_full_container"
5
7
  :size="size"
6
8
  >
@@ -12,6 +14,8 @@
12
14
  </SpinnerContainer>
13
15
  <Container
14
16
  v-else
17
+ data-id="spinner_container"
18
+ data-qa-id="spinner_container"
15
19
  data-test-id="spinner_container"
16
20
  :limited-to-modal="limitedToModal"
17
21
  >
@@ -1,5 +1,10 @@
1
1
  <template>
2
- <SpinnerContainer v-if="fullWidth" data-test-id="spinner_full_container">
2
+ <SpinnerContainer
3
+ v-if="fullWidth"
4
+ data-id="spinner_full_container"
5
+ data-qa-id="spinner_full_container"
6
+ data-test-id="spinner_full_container"
7
+ >
3
8
  <Container>
4
9
  <SpinnerWrapper data-test-id="spinner_full_wrapper" :size="size">
5
10
  <img
@@ -13,6 +18,8 @@
13
18
  </SpinnerContainer>
14
19
  <Container
15
20
  v-else
21
+ data-id="spinner_container"
22
+ data-qa-id="spinner_container"
16
23
  data-test-id="spinner_container"
17
24
  :limited-to-modal="limitedToModal"
18
25
  >
@@ -0,0 +1,101 @@
1
+ /* eslint-disable */
2
+ import { mount } from '@vue/test-utils'
3
+ import TabsHeader from './index.vue'
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
+ describe('TabsHeader', () => {
12
+ const mockTabsData = [
13
+ {
14
+ text: 'Tab 1',
15
+ id: 0,
16
+ hasError: true,
17
+ icon: 'home',
18
+ subText: 'Subtext 1',
19
+ },
20
+ {
21
+ text: 'Tab 2',
22
+ id: 1,
23
+ hasError: false,
24
+ icon: 'settings',
25
+ subText: 'Subtext 2',
26
+ },
27
+ ]
28
+
29
+ const createWrapper = (props = {}) => {
30
+ return mount(TabsHeader, {
31
+ props: {
32
+ tabsData: mockTabsData,
33
+ activeTab: 0,
34
+ fullSize: true,
35
+ ...props,
36
+ },
37
+ global: {
38
+ mocks: {
39
+ theme,
40
+ },
41
+ },
42
+ })
43
+ }
44
+
45
+ it('renders all tabs correctly', () => {
46
+ const wrapper = createWrapper()
47
+ const tabs = wrapper.findAll('[data-test-id="tab-item"]')
48
+ expect(tabs).toHaveLength(mockTabsData.length)
49
+ })
50
+
51
+ it('displays correct tab text', () => {
52
+ const wrapper = createWrapper()
53
+ const firstTab = wrapper.find('[data-test-id="tab-text"]')
54
+ expect(firstTab.text()).toBe('Tab 1')
55
+ })
56
+
57
+ it('emits on-tab-change event when clicking a tab', async () => {
58
+ const wrapper = createWrapper()
59
+ const tabs = wrapper.findAll('[data-test-id="tab-item"]')
60
+ await tabs[1].trigger('click')
61
+ expect(wrapper.emitted('on-tab-change')).toBeTruthy()
62
+ expect(wrapper.emitted('on-tab-change')[0]).toEqual([1])
63
+ })
64
+
65
+ it('does not emit on-tab-change when clicking active tab', async () => {
66
+ const wrapper = createWrapper()
67
+ const activeTab = wrapper.find('[data-test-id="tab-item"]')
68
+ await activeTab.trigger('click')
69
+ expect(wrapper.emitted('on-tab-change')).toBeFalsy()
70
+ })
71
+
72
+ it('applies correct styles for active tab', () => {
73
+ const wrapper = createWrapper()
74
+ const activeTab = wrapper.find('[data-test-active="true"]')
75
+ expect(activeTab.exists()).toBe(true)
76
+ })
77
+
78
+ it('renders error icon when tab has error', () => {
79
+ const wrapper = createWrapper()
80
+ const warningIcon = wrapper.find('[data-test-id="warning-icon"]')
81
+ expect(warningIcon.exists()).toBe(true)
82
+ })
83
+
84
+ it('renders subtext when provided', () => {
85
+ const wrapper = createWrapper()
86
+ const subtext = wrapper.find('[data-test-id="tab-subtext"]')
87
+ expect(subtext.text()).toBe('Subtext 1')
88
+ })
89
+
90
+ it('renders icon when provided', () => {
91
+ const wrapper = createWrapper()
92
+ const icon = wrapper.find('[data-test-id="tab-icon"]')
93
+ expect(icon.exists()).toBe(true)
94
+ })
95
+
96
+ it('applies fullSize prop correctly', () => {
97
+ const wrapper = createWrapper({ fullSize: true })
98
+ const tabs = wrapper.findAll('[data-test-id="tab-item"]')
99
+ expect(tabs.length).toBeGreaterThan(0)
100
+ })
101
+ })
@@ -1,10 +1,12 @@
1
1
  <template>
2
- <PageContainer>
3
- <TabsContainer>
2
+ <PageContainer data-test-id="tabs-header-container">
3
+ <TabsContainer data-test-id="tabs-container">
4
4
  <TabItem
5
5
  v-for="item in tabsData"
6
6
  :key="item.id"
7
7
  :data-id="item.dataId"
8
+ :data-test-active="activeTab === item.id"
9
+ data-test-id="tab-item"
8
10
  :full-size="fullSize"
9
11
  :is-active="activeTab === item.id"
10
12
  @click="onTabClick({ id: item.id })"
@@ -16,6 +18,7 @@
16
18
  ? theme.semanticColors.purple[500]
17
19
  : theme.semanticColors.teal[800]
18
20
  "
21
+ data-test-id="tab-icon"
19
22
  :hovered-color="
20
23
  activeTab === item.id
21
24
  ? theme.semanticColors.purple[500]
@@ -24,10 +27,21 @@
24
27
  :name="item.icon"
25
28
  size="14px"
26
29
  />
27
- <div>{{ item.text }}</div>
28
- <DotIcon v-if="item.subText" :is-active="activeTab === item.id" />
29
- <SubText v-if="item.subText">{{ item.subText }}</SubText>
30
- <RCIcon v-if="item.hasError" name="warning" size="14px" />
30
+ <div data-test-id="tab-text">{{ item.text }}</div>
31
+ <DotIcon
32
+ v-if="item.subText"
33
+ data-test-id="dot-icon"
34
+ :is-active="activeTab === item.id"
35
+ />
36
+ <SubText v-if="item.subText" data-test-id="tab-subtext">{{
37
+ item.subText
38
+ }}</SubText>
39
+ <RCIcon
40
+ v-if="item.hasError"
41
+ data-test-id="warning-icon"
42
+ name="warning"
43
+ size="14px"
44
+ />
31
45
  </TabItem>
32
46
  </TabsContainer>
33
47
  </PageContainer>
@@ -112,7 +126,6 @@
112
126
  components: {
113
127
  PageContainer,
114
128
  TabsContainer,
115
- NameContainer,
116
129
  TabItem,
117
130
  SubText,
118
131
  DotIcon,