Skip to content

Commit 0446255

Browse files
daveearleyclaude
andcommitted
Simplify check-in list form + add Callout component
Progressive disclosure: essentials (name + tickets) always visible, description/dates/visibility behind a single "Advanced options" toggle that auto-opens when those fields are already set. Redesign visibility section as a labeled-row card with per-row icons (notes/Q&A/order) instead of loose switches behind a divider. New reusable Callout component replaces Mantine Alert for contextual nudges — soft tinted background, minimal stroke icon, optional title and dismiss. Four variants: info/tip/warning/success. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
1 parent e43f504 commit 0446255

36 files changed

Lines changed: 1706 additions & 820 deletions
Lines changed: 118 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,118 @@
1+
.callout {
2+
position: relative;
3+
display: flex;
4+
gap: 12px;
5+
align-items: flex-start;
6+
padding: 14px 16px;
7+
border-radius: 14px;
8+
margin-bottom: 16px;
9+
// Faint left accent stripe via box-shadow inset — no wasted horizontal space.
10+
overflow: hidden;
11+
background: #fff;
12+
border: 1px solid var(--hi-color-gray-2);
13+
}
14+
15+
.info {
16+
background: linear-gradient(135deg, color-mix(in srgb, var(--mantine-color-primary-5) 6%, #fff), #fff 55%);
17+
border-color: color-mix(in srgb, var(--mantine-color-primary-5) 22%, transparent);
18+
}
19+
20+
.tip {
21+
background: linear-gradient(135deg, color-mix(in srgb, #f59f00 8%, #fff), #fff 55%);
22+
border-color: color-mix(in srgb, #f59f00 26%, transparent);
23+
}
24+
25+
.warning {
26+
background: linear-gradient(135deg, color-mix(in srgb, #e03131 8%, #fff), #fff 55%);
27+
border-color: color-mix(in srgb, #e03131 28%, transparent);
28+
}
29+
30+
.success {
31+
background: linear-gradient(135deg, color-mix(in srgb, var(--hi-color-money-green) 10%, #fff), #fff 55%);
32+
border-color: color-mix(in srgb, var(--hi-color-money-green) 30%, transparent);
33+
}
34+
35+
.iconWrap {
36+
width: 22px;
37+
height: 22px;
38+
display: flex;
39+
align-items: center;
40+
justify-content: center;
41+
flex-shrink: 0;
42+
margin-top: 1px;
43+
background: transparent;
44+
}
45+
46+
.iconWrap_info {
47+
color: var(--mantine-color-primary-7);
48+
}
49+
50+
.iconWrap_tip {
51+
color: #b46400;
52+
}
53+
54+
.iconWrap_warning {
55+
color: #c92a2a;
56+
}
57+
58+
.iconWrap_success {
59+
color: #087f5b;
60+
}
61+
62+
.body {
63+
flex: 1;
64+
min-width: 0;
65+
padding-top: 1px;
66+
}
67+
68+
.title {
69+
font-size: 14px;
70+
font-weight: 700;
71+
color: var(--hi-text);
72+
line-height: 1.3;
73+
letter-spacing: -0.01em;
74+
margin-bottom: 3px;
75+
}
76+
77+
.text {
78+
font-size: 13px;
79+
line-height: 1.5;
80+
color: var(--hi-color-gray-dark);
81+
82+
a {
83+
color: var(--hi-primary);
84+
font-weight: 600;
85+
}
86+
87+
b, strong {
88+
color: var(--hi-text);
89+
font-weight: 600;
90+
}
91+
}
92+
93+
.dismissBtn {
94+
position: absolute;
95+
top: 8px;
96+
right: 8px;
97+
width: 24px;
98+
height: 24px;
99+
border-radius: 50%;
100+
border: none;
101+
background: transparent;
102+
color: var(--hi-color-gray-dark);
103+
display: flex;
104+
align-items: center;
105+
justify-content: center;
106+
cursor: pointer;
107+
transition: background 140ms ease, color 140ms ease;
108+
109+
&:hover {
110+
background: var(--hi-color-gray);
111+
color: var(--hi-text);
112+
}
113+
114+
&:focus-visible {
115+
outline: 2px solid var(--hi-primary);
116+
outline-offset: 1px;
117+
}
118+
}
Lines changed: 64 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,64 @@
1+
import {ReactNode} from "react";
2+
import {t} from "@lingui/macro";
3+
import {
4+
IconAlertTriangle,
5+
IconBulb,
6+
IconCheck,
7+
IconInfoCircle,
8+
IconX,
9+
} from "@tabler/icons-react";
10+
import classes from "./Callout.module.scss";
11+
12+
export type CalloutVariant = "info" | "tip" | "warning" | "success";
13+
14+
interface CalloutProps {
15+
variant?: CalloutVariant;
16+
title?: ReactNode;
17+
children: ReactNode;
18+
icon?: ReactNode;
19+
onDismiss?: () => void;
20+
className?: string;
21+
}
22+
23+
const defaultIcon: Record<CalloutVariant, ReactNode> = {
24+
info: <IconInfoCircle size={18} stroke={2}/>,
25+
tip: <IconBulb size={18} stroke={2}/>,
26+
warning: <IconAlertTriangle size={18} stroke={2}/>,
27+
success: <IconCheck size={18} stroke={2.4}/>,
28+
};
29+
30+
/**
31+
* Callout — a friendlier alternative to Mantine's Alert for contextual hints, onboarding
32+
* nudges, and helpful framing inside forms. Use it over Alert when the tone should feel
33+
* conversational rather than "system-generated".
34+
*/
35+
export const Callout = ({
36+
variant = "info",
37+
title,
38+
children,
39+
icon,
40+
onDismiss,
41+
className,
42+
}: CalloutProps) => {
43+
return (
44+
<aside className={`${classes.callout} ${classes[variant]} ${className ?? ""}`}>
45+
<div className={`${classes.iconWrap} ${classes[`iconWrap_${variant}`]}`} aria-hidden="true">
46+
{icon ?? defaultIcon[variant]}
47+
</div>
48+
<div className={classes.body}>
49+
{title && <div className={classes.title}>{title}</div>}
50+
<div className={classes.text}>{children}</div>
51+
</div>
52+
{onDismiss && (
53+
<button
54+
type="button"
55+
onClick={onDismiss}
56+
className={classes.dismissBtn}
57+
aria-label={t`Dismiss`}
58+
>
59+
<IconX size={14}/>
60+
</button>
61+
)}
62+
</aside>
63+
);
64+
};
Lines changed: 121 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,121 @@
1+
.advancedToggle {
2+
display: flex;
3+
align-items: center;
4+
gap: 6px;
5+
background: transparent;
6+
border: none;
7+
color: var(--hi-primary);
8+
font-family: inherit;
9+
font-size: 13px;
10+
font-weight: 600;
11+
cursor: pointer;
12+
padding: 6px 8px;
13+
margin: 4px 0 12px -8px;
14+
border-radius: 6px;
15+
transition: background 140ms ease;
16+
17+
&:hover {
18+
background: color-mix(in srgb, var(--hi-primary) 8%, transparent);
19+
}
20+
21+
&:focus-visible {
22+
outline: 2px solid var(--hi-primary);
23+
outline-offset: 1px;
24+
}
25+
26+
.chevron {
27+
transition: transform 180ms ease;
28+
29+
&.chevronOpen {
30+
transform: rotate(90deg);
31+
}
32+
}
33+
}
34+
35+
.visibilitySection {
36+
margin-top: 20px;
37+
padding: 16px;
38+
background: var(--hi-color-gray);
39+
border-radius: 12px;
40+
border: 1px solid var(--hi-color-gray-2);
41+
}
42+
43+
.visibilityHeader {
44+
display: flex;
45+
align-items: flex-start;
46+
gap: 10px;
47+
margin-bottom: 14px;
48+
}
49+
50+
.visibilityIcon {
51+
width: 32px;
52+
height: 32px;
53+
border-radius: 8px;
54+
background: #fff;
55+
border: 1px solid var(--hi-color-gray-2);
56+
display: flex;
57+
align-items: center;
58+
justify-content: center;
59+
color: var(--hi-color-gray-dark);
60+
flex-shrink: 0;
61+
}
62+
63+
.visibilityTitle {
64+
font-size: 14px;
65+
font-weight: 700;
66+
color: var(--hi-text);
67+
line-height: 1.3;
68+
letter-spacing: -0.01em;
69+
}
70+
71+
.visibilityHint {
72+
font-size: 12px;
73+
color: var(--hi-color-gray-dark);
74+
line-height: 1.4;
75+
margin-top: 2px;
76+
}
77+
78+
.visibilityRows {
79+
display: flex;
80+
flex-direction: column;
81+
gap: 4px;
82+
}
83+
84+
.visibilityRow {
85+
display: flex;
86+
align-items: center;
87+
gap: 12px;
88+
padding: 10px 12px;
89+
background: #fff;
90+
border: 1px solid var(--hi-color-gray-2);
91+
border-radius: 10px;
92+
}
93+
94+
.visibilityRowIcon {
95+
width: 28px;
96+
height: 28px;
97+
border-radius: 50%;
98+
background: var(--hi-color-gray);
99+
display: flex;
100+
align-items: center;
101+
justify-content: center;
102+
color: var(--hi-color-gray-dark);
103+
flex-shrink: 0;
104+
}
105+
106+
.visibilityRowMain {
107+
flex: 1;
108+
min-width: 0;
109+
}
110+
111+
.visibilityRowLabel {
112+
font-size: 13px;
113+
font-weight: 600;
114+
color: var(--hi-text);
115+
}
116+
117+
.visibilityRowDesc {
118+
font-size: 12px;
119+
color: var(--hi-color-gray-dark);
120+
margin-top: 1px;
121+
}

0 commit comments

Comments
 (0)