Skip to content

Commit 6d6a95e

Browse files
committed
front: ui-core input tooltip status messages
Signed-off-by: Egor Berezovskiy <[email protected]>
1 parent ab0f830 commit 6d6a95e

File tree

4 files changed

+102
-5
lines changed

4 files changed

+102
-5
lines changed

ui-core/src/components/inputs/Input.tsx

+1
Original file line numberDiff line numberDiff line change
@@ -86,6 +86,7 @@ const Input = React.forwardRef<HTMLInputElement, InputProps>(
8686
disabled={disabled}
8787
required={required}
8888
small={small}
89+
statusIconPosition="before-status-message"
8990
className={cx('input-field-wrapper', inputFieldWrapperClassname)}
9091
>
9192
<div

ui-core/src/components/inputs/StatusMessage.tsx

+11-2
Original file line numberDiff line numberDiff line change
@@ -5,8 +5,10 @@ import cx from 'classnames';
55
import InputStatusIcon from './InputStatusIcon';
66

77
export type Status = 'success' | 'info' | 'error' | 'warning' | 'loading';
8+
export type TooltipType = 'left' | 'right';
89

910
export type StatusWithMessage = {
11+
tooltip?: TooltipType;
1012
status: Status;
1113
message?: string;
1214
};
@@ -18,11 +20,18 @@ export type StatusMessageProps = {
1820
};
1921

2022
const StatusMessage = ({ statusWithMessage, showIcon, small }: StatusMessageProps) => {
21-
const { status, message } = statusWithMessage;
23+
const { tooltip, status, message } = statusWithMessage;
2224
if (message === undefined) return null;
2325

2426
return (
25-
<div className="status-message-wrapper">
27+
<div
28+
className={cx({
29+
'status-message-wrapper': !tooltip,
30+
'status-message-wrapper-tooltip': tooltip,
31+
'tooltip-left': tooltip === 'left',
32+
'tooltip-right': tooltip === 'right',
33+
})}
34+
>
2635
{showIcon && <InputStatusIcon status={status} small={small} />}
2736
<span className={cx('status-message', { [status]: status })}>{message}</span>
2837
</div>

ui-core/src/stories/Input.stories.tsx

+34
Original file line numberDiff line numberDiff line change
@@ -172,6 +172,40 @@ export const ErrorInput: Story = {
172172
},
173173
},
174174
};
175+
export const TooltipErrorInput: Story = {
176+
decorators: [
177+
(Story) => (
178+
<div style={{ display: 'flex', flexDirection: 'row', gap: '20px' }}>
179+
<Story
180+
args={{
181+
label: 'Name',
182+
type: 'text',
183+
value: 'Michel Sardou',
184+
statusWithMessage: {
185+
tooltip: 'left',
186+
status: 'error',
187+
message: 'Michel Sardou can’t be used',
188+
},
189+
statusIconPosition: 'before-status-message',
190+
}}
191+
/>
192+
<Story
193+
args={{
194+
label: 'Name',
195+
type: 'text',
196+
value: 'Jean-Michel Halleurt',
197+
statusWithMessage: {
198+
tooltip: 'right',
199+
status: 'error',
200+
message: 'Jean-Michel Halleurt can’t be used with a very very very very very very very very very long message',
201+
},
202+
statusIconPosition: 'before-status-message',
203+
}}
204+
/>
205+
</div>
206+
),
207+
],
208+
};
175209

176210
export const ErrorWithoutMessageInput: Story = {
177211
args: {
+56-3
Original file line numberDiff line numberDiff line change
@@ -1,23 +1,28 @@
1+
:root {
2+
--tooltip-transition-duration: 0.2s;
3+
}
4+
15
.feed-back {
26
border-radius: 0.5rem;
37
position: relative;
48
padding: 0.625rem 0.813rem 1rem 1rem;
59

6-
&.info {
10+
&.info:not(:has(.status-message-wrapper-tooltip)) {
711
@apply bg-info-5;
812
}
913

10-
&.warning {
14+
&.warning:not(:has(.status-message-wrapper-tooltip)) {
1115
@apply bg-warning-5;
1216
}
1317

14-
&.error {
18+
&.error:not(:has(.status-message-wrapper-tooltip)) {
1519
@apply bg-error-5;
1620
}
1721

1822
.custom-field {
1923
display: flex;
2024
flex-direction: column;
25+
position: relative;
2126

2227
.field-and-status-icon,
2328
.field-wrapper-status-message {
@@ -28,5 +33,53 @@
2833
margin-left: 0.563rem;
2934
}
3035
}
36+
37+
input:focus:has(.status-message-wrapper-tooltip) .status-message-wrapper-tooltip {
38+
z-index: 2;
39+
}
40+
41+
.status-message-wrapper-tooltip {
42+
position: absolute;
43+
display: flex;
44+
align-items: center;
45+
width: 320px;
46+
top: 60px;
47+
gap: 12px;
48+
border-radius: 8px;
49+
box-shadow:
50+
0px 10px 20px 0px rgba(0, 0, 0, 0.2),
51+
0px 1px 0px rgba(255, 255, 255, 0.6) inset;
52+
background-color: theme('colors.error.5');
53+
opacity: 1;
54+
padding: 8px 12px;
55+
min-height: 64px;
56+
57+
z-index: 10;
58+
transition: var(--tooltip-transition-duration) ease;
59+
60+
.status-message {
61+
opacity: 1;
62+
color: theme('colors.error.60');
63+
font-size: 16px;
64+
font-weight: 600;
65+
font-style: SemiBold;
66+
letter-spacing: 0px;
67+
text-align: left;
68+
line-height: 24px;
69+
}
70+
}
71+
.tooltip-left {
72+
left: -5px;
73+
}
74+
75+
.tooltip-right {
76+
right: -5px;
77+
}
78+
}
79+
}
80+
81+
@media (prefers-reduced-motion: reduce) {
82+
:root {
83+
--tooltip-transition-duration: 0s;
3184
}
3285
}

0 commit comments

Comments
 (0)