@farm-investimentos/front-mfe-components 15.10.1 → 15.11.0

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": "@farm-investimentos/front-mfe-components",
3
- "version": "15.10.1",
3
+ "version": "15.11.0",
4
4
  "author": "farm investimentos",
5
5
  "private": false,
6
6
  "main": "./dist/front-mfe-components.common.js",
@@ -101,12 +101,12 @@ export const ValidacaoInputPadrao = () => ({
101
101
  };
102
102
  },
103
103
  template: `<div style='max-width: 320px'>
104
- <farm-label>Selecione uma data entre 01/01/2024 e 31/12/2024</farm-label>
104
+ <farm-label>Selecione uma data entre 01/01/2025 e 31/12/2025</farm-label>
105
105
  <RangeDatePicker
106
106
  inputId="input-custom-id"
107
107
  v-model="date"
108
- min="2024-01-01"
109
- max="2024-12-31"
108
+ min="2025-01-01"
109
+ max="2025-12-31"
110
110
  validateInput
111
111
  required
112
112
  />
@@ -121,15 +121,15 @@ export const ValidacaoInputCustomizada = () => ({
121
121
  };
122
122
  },
123
123
  template: `<div style='max-width: 320px'>
124
- <farm-label>Selecione uma data do primeiro semestre de 2024</farm-label>
124
+ <farm-label>Selecione uma data do primeiro semestre de 2025</farm-label>
125
125
  <RangeDatePicker
126
126
  inputId="input-custom-id"
127
127
  v-model="date"
128
- min="2024-01-01"
129
- max="2024-06-30"
128
+ min="2025-01-01"
129
+ max="2025-06-30"
130
130
  validateInput
131
131
  required
132
- outOfRangeMessage="Por favor, selecione datas dentro do primeiro semestre de 2024 ({min} até {max})"
132
+ outOfRangeMessage="Por favor, selecione datas dentro do primeiro semestre de 2025 ({min} até {max})"
133
133
  />
134
134
  date: {{ date }}
135
135
  </div>`,
@@ -164,15 +164,16 @@ export default defineComponent({
164
164
  return true;
165
165
  }
166
166
 
167
- const [startDate, endDate] = value.split(' a ').map(date => {
168
- const [day, month, year] = date.split('/');
169
- return new Date(year, month - 1, day);
170
- });
171
-
167
+ const [startDateStr, endDateStr] = value.split(' a ');
168
+
169
+ const startDate = new Date(convertDate(startDateStr));
170
+ const endDate = new Date(convertDate(endDateStr));
172
171
  const minDate = new Date(this.min);
173
172
  const maxDate = new Date(this.max);
174
173
 
175
- if (startDate < minDate || endDate > maxDate) {
174
+ const isValid = startDate.getTime() >= minDate.getTime() && endDate.getTime() <= maxDate.getTime();
175
+
176
+ if (!isValid) {
176
177
  return this.outOfRangeMessage
177
178
  .replace('{min}', dateDefaultFormatter(this.min))
178
179
  .replace('{max}', dateDefaultFormatter(this.max));
@@ -104,4 +104,49 @@ describe('RangeDatePicker component', () => {
104
104
  expect(component.fieldRange).toEqual('27/02/2023 a 28/02/2023');
105
105
  });
106
106
  });
107
+
108
+ describe('range validation', () => {
109
+ beforeEach(async () => {
110
+ await wrapper.setProps({
111
+ min: '2023-02-01',
112
+ max: '2023-02-28',
113
+ validateInput: true
114
+ });
115
+ });
116
+
117
+ it('should return true when date range is within min and max', () => {
118
+ const result = component.checkMinMax('15/02/2023 a 20/02/2023');
119
+ expect(result).toBe(true);
120
+ });
121
+
122
+ it('should return error message when start date is before min date', () => {
123
+ const result = component.checkMinMax('31/01/2023 a 15/02/2023');
124
+ expect(result).toBe('A data selecionada deve ser entre 01/02/2023 e 28/02/2023');
125
+ });
126
+
127
+ it('should return error message when end date is after max date', () => {
128
+ const result = component.checkMinMax('15/02/2023 a 01/03/2023');
129
+ expect(result).toBe('A data selecionada deve ser entre 01/02/2023 e 28/02/2023');
130
+ });
131
+
132
+ it('should return true when validateInput is false', async () => {
133
+ await wrapper.setProps({ validateInput: false });
134
+ const result = component.checkMinMax('31/01/2023 a 01/03/2023');
135
+ expect(result).toBe(true);
136
+ });
137
+
138
+ it('should return true when value is empty', () => {
139
+ const result = component.checkMinMax('');
140
+ expect(result).toBe(true);
141
+ });
142
+
143
+ it('should return true when min and max are not set', async () => {
144
+ await wrapper.setProps({
145
+ min: null,
146
+ max: null
147
+ });
148
+ const result = component.checkMinMax('15/02/2023 a 20/02/2023');
149
+ expect(result).toBe(true);
150
+ });
151
+ });
107
152
  });
@@ -1,6 +1,9 @@
1
- @import '../../configurations/theme-colors';
2
1
  @import '../../configurations/variables';
3
2
 
3
+ $arrow-size: 6px;
4
+ $tooltip-color: #333333;
5
+ $arrow-margin: 12px;
6
+
4
7
  .farm-tooltip {
5
8
  display: inline-block;
6
9
  position: relative;
@@ -11,31 +14,110 @@
11
14
  }
12
15
 
13
16
  .farm-tooltip__popup {
14
- background-color: rgba(themeColor('primary'), 0.95);
15
- @each $color in $theme-colors-list {
16
- &.farm-tooltip--#{$color} {
17
- background-color: rgba(themeColor($color), 0.95);
18
- }
19
- }
20
- }
21
-
22
- .farm-tooltip__popup {
17
+ background-color: $tooltip-color;
23
18
  visibility: hidden;
24
19
  opacity: 0;
25
20
  transition: visibility 0.3s linear, opacity 0.3s linear;
26
21
  position: absolute;
27
22
  width: 160px;
28
- contain: content;
29
- color: white;
23
+ color: #f5f5f5;
30
24
  border-radius: 5px;
31
25
  font-family: 'Manrope', sans-serif !important;
32
26
  font-size: 12px;
33
27
  font-weight: 500px;
34
- padding: 8px 12px;
28
+ padding: 16px;
35
29
  display: block;
30
+ z-index: 9999;
31
+
32
+ &--fluid {
33
+ width: auto;
34
+ min-width: 160px;
35
+ max-width: 300px;
36
+ }
36
37
 
37
38
  &--visible {
38
39
  opacity: 1;
39
40
  visibility: visible;
40
41
  }
42
+
43
+ .farm-tooltip__header {
44
+ display: flex;
45
+ justify-content: space-between;
46
+ align-items: center;
47
+ margin-bottom: 8px;
48
+ }
49
+
50
+ .farm-tooltip__title {
51
+ font-weight: 600;
52
+ font-size: 13px;
53
+ margin-right: 16px;
54
+ }
55
+
56
+ .farm-tooltip__content {
57
+ font-weight: 500;
58
+ }
59
+
60
+ .farm-tooltip__arrow {
61
+ position: absolute;
62
+ width: 0;
63
+ height: 0;
64
+ border-style: solid;
65
+ z-index: 10000;
66
+ }
67
+
68
+ // Top positions - arrow at bottom
69
+ &--top-center .farm-tooltip__arrow,
70
+ &--top-left .farm-tooltip__arrow,
71
+ &--top-right .farm-tooltip__arrow {
72
+ border-width: $arrow-size $arrow-size 0 $arrow-size;
73
+ border-color: $tooltip-color transparent transparent transparent;
74
+ bottom: -$arrow-size;
75
+ z-index: 99999;
76
+ }
77
+
78
+ // Bottom positions - arrow at top
79
+ &--bottom-center .farm-tooltip__arrow,
80
+ &--bottom-left .farm-tooltip__arrow,
81
+ &--bottom-right .farm-tooltip__arrow {
82
+ border-width: 0 $arrow-size $arrow-size $arrow-size;
83
+ border-color: transparent transparent $tooltip-color transparent;
84
+ top: -$arrow-size;
85
+ z-index: 99999;
86
+ }
87
+
88
+ // Left alignment - arrow at left
89
+ &--top-left .farm-tooltip__arrow,
90
+ &--bottom-left .farm-tooltip__arrow {
91
+ left: $arrow-margin;
92
+ }
93
+
94
+ // Right alignment - arrow at right
95
+ &--top-right .farm-tooltip__arrow,
96
+ &--bottom-right .farm-tooltip__arrow {
97
+ right: $arrow-margin;
98
+ }
99
+
100
+ // Center alignment - arrow at center
101
+ &--top-center .farm-tooltip__arrow,
102
+ &--bottom-center .farm-tooltip__arrow {
103
+ left: 50%;
104
+ transform: translateX(-50%);
105
+ }
106
+
107
+ .farm-tooltip__close {
108
+ position: relative;
109
+ width: 16px;
110
+ height: 16px;
111
+ line-height: 16px;
112
+ text-align: center;
113
+ cursor: pointer;
114
+ font-size: 16px;
115
+ color: #f5f5f5;
116
+ }
117
+
118
+ &:not(.farm-tooltip__popup--has-title) .farm-tooltip__close {
119
+ position: absolute;
120
+ top: 8px;
121
+ right: 8px;
122
+ }
41
123
  }
@@ -1,7 +1,5 @@
1
1
  import { withDesign } from 'storybook-addon-designs';
2
2
  import Tooltip from '.';
3
- import baseThemeColors from '../../configurations/_theme-colors-base.scss';
4
- const colors = Object.keys(baseThemeColors);
5
3
 
6
4
  export default {
7
5
  title: 'Interactions/Tooltip',
@@ -13,6 +11,16 @@ export default {
13
11
  component: `Tooltip<br />
14
12
  selector: <em>farm-tooltip</em><br />
15
13
  <span style="color: var(--farm-primary-base);">ready for use</span>
14
+ <br /><br />
15
+ <h3>Important notes:</h3>
16
+ <ul>
17
+ <li><strong>Do not add margin to the activator element</strong> - This can confuse the tooltip display watcher and prevent the arrow from being positioned correctly</li>
18
+ <li>Prefer to add margin to the parent element or sibling elements of the tooltip</li>
19
+ <li>Arrow positioning is calculated based on the activator element position</li>
20
+ <li>The close button (X) is automatically displayed only in tooltips controlled by v-model</li>
21
+ <li>The arrow is only displayed when a position is explicitly defined (position property). If no position is defined, the tooltip will not have an arrow</li>
22
+ <li>You can add a title to the tooltip using the "title" slot. When used in a controlled tooltip, the close button will be aligned with the title</li>
23
+ </ul>
16
24
  `,
17
25
  },
18
26
  },
@@ -25,76 +33,173 @@ export default {
25
33
  };
26
34
 
27
35
  export const Tooltips = () => ({
28
- data() {
29
- return {
30
- colors,
31
- };
32
- },
33
36
  template: `<div style="padding-left: 80px; padding-top: 80px;">
34
- <farm-tooltip
35
- v-for="color of colors"
36
- :key="color"
37
- :color="color"
38
- style="margin-right: 4px"
39
- >
40
- <span>
41
- this is the tooltip for {{ color }}
42
- </span>
43
- <template v-slot:activator="{ on, attrs }">
44
- {{ color }}
45
- </template>
46
- </farm-tooltip>
37
+ <span style="display: flex; align-items: center;">
38
+ Hover over the icon
39
+ <farm-tooltip>
40
+ <span>
41
+ This is a simple tooltip
42
+ </span>
43
+ <template v-slot:activator>
44
+ <farm-icon size="sm" color="gray" style="margin-left: 8px; cursor: help;">help-circle</farm-icon>
45
+ </template>
46
+ </farm-tooltip>
47
+ </span>
47
48
  </div>`,
48
49
  });
49
50
 
50
- export const Iconed = () => ({
51
+ export const InsideCard = () => ({
51
52
  template: `<div style="padding-left: 80px; padding-top: 80px;">
52
- <farm-tooltip>
53
- some <em>sample</em> text
54
- <br />with line break
55
- <br />and a long text that does not fit
56
- <template v-slot:activator="{ on, attrs }">
57
- <farm-icon size="sm" color="gray">help-circle</farm-icon>
58
- </template>
59
- </farm-tooltip>
53
+ <farm-card style="padding: 32px">
54
+ <span style="display: flex; align-items: center;">
55
+ <span style="margin-right: 8px;">Important information</span>
56
+ <farm-tooltip>
57
+ this is the tooltip!
58
+ <template v-slot:activator>
59
+ <farm-icon size="sm" color="gray" style="cursor: help;">help-circle</farm-icon>
60
+ </template>
61
+ </farm-tooltip>
62
+ </span>
63
+ </farm-card>
60
64
  </div>`,
61
65
  });
62
66
 
63
- export const Visibility = () => ({
64
- data() {
65
- return {
66
- show: false,
67
- };
68
- },
67
+ export const FluidTooltip = () => ({
69
68
  template: `<div style="padding-left: 80px; padding-top: 80px;">
70
- <farm-tooltip v-model="show">
71
- some <em>sample</em> text<br />
72
- some <em>sample</em> text<br />
73
- some <em>sample</em> text<br />
74
- some <em>sample</em> text<br />
75
- some <em>sample</em> text<br />
76
- some <em>sample</em> text<br />
77
- some <em>sample</em> text<br />
78
- some <em>sample</em> text<br />
79
- some <em>sample</em> text<br />
80
- <template v-slot:activator="{ on, attrs }">
81
- <farm-btn @click="show = !show">
82
- toggle me
83
- </farm-btn>
84
- </template>
85
- </farm-tooltip>
69
+ <span style="display: flex; align-items: center;">
70
+ <span style="margin-right: 8px;">Fluid width tooltip</span>
71
+ <farm-tooltip fluid>
72
+ This is a fluid tooltip that will grow based on its content.
73
+ It contains a longer text to demonstrate how it expands horizontally.
74
+ <template v-slot:activator>
75
+ <farm-icon size="sm" color="gray" style="cursor: help;">help-circle</farm-icon>
76
+ </template>
77
+ </farm-tooltip>
78
+ </span>
86
79
  </div>`,
87
80
  });
88
81
 
89
- export const InsideCard = () => ({
82
+ export const TooltipPositions = () => ({
83
+ template: `<div style="padding: 100px; display: flex; flex-direction: column; align-items: center; gap: 50px;">
84
+ <div style="display: flex; gap: 30px; margin-bottom: 50px;">
85
+ <div style="display: flex; flex-direction: column; align-items: center;">
86
+ <p style="margin-bottom: 10px;">Top Left</p>
87
+ <farm-tooltip position="top-left">
88
+ Top-Left Position
89
+ <template v-slot:activator>
90
+ <farm-icon size="md" color="gray" style="cursor: help;">help-circle</farm-icon>
91
+ </template>
92
+ </farm-tooltip>
93
+ </div>
94
+
95
+ <div style="display: flex; flex-direction: column; align-items: center;">
96
+ <p style="margin-bottom: 10px;">Top Center</p>
97
+ <farm-tooltip position="top-center">
98
+ Top-Center Position (Default)
99
+ <template v-slot:activator>
100
+ <farm-icon size="md" color="gray" style="cursor: help;">help-circle</farm-icon>
101
+ </template>
102
+ </farm-tooltip>
103
+ </div>
104
+
105
+ <div style="display: flex; flex-direction: column; align-items: center;">
106
+ <p style="margin-bottom: 10px;">Top Right</p>
107
+ <farm-tooltip position="top-right">
108
+ Top-Right Position
109
+ <template v-slot:activator>
110
+ <farm-icon size="md" color="gray" style="cursor: help;">help-circle</farm-icon>
111
+ </template>
112
+ </farm-tooltip>
113
+ </div>
114
+ </div>
115
+
116
+ <div style="display: flex; gap: 30px;">
117
+ <div style="display: flex; flex-direction: column; align-items: center;">
118
+ <p style="margin-bottom: 10px;">Bottom Left</p>
119
+ <farm-tooltip position="bottom-left">
120
+ Bottom-Left Position
121
+ <template v-slot:activator>
122
+ <farm-icon size="md" color="gray" style="cursor: help;">help-circle</farm-icon>
123
+ </template>
124
+ </farm-tooltip>
125
+ </div>
126
+
127
+ <div style="display: flex; flex-direction: column; align-items: center;">
128
+ <p style="margin-bottom: 10px;">Bottom Center</p>
129
+ <farm-tooltip position="bottom-center">
130
+ Bottom-Center Position
131
+ <template v-slot:activator>
132
+ <farm-icon size="md" color="gray" style="cursor: help;">help-circle</farm-icon>
133
+ </template>
134
+ </farm-tooltip>
135
+ </div>
136
+
137
+ <div style="display: flex; flex-direction: column; align-items: center;">
138
+ <p style="margin-bottom: 10px;">Bottom Right</p>
139
+ <farm-tooltip position="bottom-right">
140
+ Bottom-Right Position
141
+ <template v-slot:activator>
142
+ <farm-icon size="md" color="gray" style="cursor: help;">help-circle</farm-icon>
143
+ </template>
144
+ </farm-tooltip>
145
+ </div>
146
+ </div>
147
+ </div>`,
148
+ });
149
+
150
+ export const FluidWithPosition = () => ({
151
+ template: `<div style="padding: 200px;">
152
+ <span style="display: flex; align-items: center;">
153
+ <span style="margin-right: 8px;">Fluid tooltip with position</span>
154
+ <farm-tooltip fluid position="bottom-left">
155
+ This is a fluid tooltip with Bottom-Left position.
156
+ Notice how it grows based on content and has the arrow in the correct position.
157
+ <template v-slot:activator>
158
+ <farm-icon size="md" color="gray" style="cursor: help;">help-circle</farm-icon>
159
+ </template>
160
+ </farm-tooltip>
161
+ </span>
162
+ </div>`,
163
+ });
164
+
165
+ export const TooltipWithTitle = () => ({
90
166
  template: `<div style="padding-left: 80px; padding-top: 80px;">
91
- <farm-card style="padding: 32px">
92
- <farm-tooltip>
93
- this is the tooltip!
94
- <template v-slot:activator="{ on, attrs }">
95
- <farm-btn style="height: 80px">try me</farm-btn>
167
+ <span style="display: flex; align-items: center;">
168
+ <span style="margin-right: 8px;">Tooltip with title</span>
169
+ <farm-tooltip fluid position="top-left">
170
+ <template v-slot:title>
171
+ <farm-icon size="sm" color="white">alert</farm-icon>
172
+ <span class="ml-10">Important Information</span>
173
+ </template>
174
+ This tooltip has a title that appears at the top.
175
+ <template v-slot:activator>
176
+ <farm-icon size="md" color="gray" style="cursor: help;">help-circle</farm-icon>
96
177
  </template>
97
178
  </farm-tooltip>
98
- </farm-card>
179
+ </span>
180
+ </div>`,
181
+ });
182
+
183
+ export const ControlledTooltipWithTitle = () => ({
184
+ data() {
185
+ return {
186
+ showTooltip: false,
187
+ };
188
+ },
189
+ template: `<div style="padding: 80px;">
190
+ <span style="display: flex; align-items: center;">
191
+ <span style="margin-right: 8px;">Click to open:</span>
192
+ <farm-tooltip fluid v-model="showTooltip" position="top-right">
193
+ <template v-slot:title>
194
+ Tooltip Title
195
+ </template>
196
+ This is a controlled tooltip with title.
197
+ <br><br>
198
+ Notice how the close button is aligned with the title.
199
+ <template v-slot:activator>
200
+ <farm-icon @click="showTooltip = !showTooltip" size="md" color="blue" style="cursor: pointer;">help-circle</farm-icon>
201
+ </template>
202
+ </farm-tooltip>
203
+ </span>
99
204
  </div>`,
100
205
  });