Skip to content

Commit

Sidebar: soon rows and the project row keep their styles inside a hint; tiny amounts read as zero

Radix asChild merges className as a string, so a NavLink's className function was lost inside Hint: Insights, Boards, Roadmap and Observability rendered bold and bright, and the project row lost its highlight. Hint now puts a plain box around a child whose className is a function, and the two sidebar rows have one. money() printed four zero decimals for a few millionths of a dollar; under a hundredth of a cent it now reads as zero dollars to the cent.

syntaqxcommitted Parentc82c972Browse files
4 files+20−10/4 viewed
+6−0
175175 }) {
176176 const { pathname } = useLocation();
177177 return (
178+ // The hint wraps a plain box: Radix's asChild merges className as a
179+ // string, which would break NavLink's className function.
178180 <Hint label={about} side="right">
181+ <div>
179182 <NavLink
180183 to={to}
181184 prefetch="intent"
190193 <span className="min-w-0 grow truncate">{children}</span>
191194 <SoonPill />
192195 </NavLink>
196+ </div>
193197 </Hint>
194198 );
195199 }
945949 <nav aria-label={`${repo.namespace}/${repo.name}`} className={PANEL}>
946950 <BackRow to={back.to} label={back.label} />
947951 <Hint label="Overview" side="right">
952+ <div>
948953 <NavLink
949954 to={base}
950955 end
961966 <span className="font-semibold text-fg">{repo.name}</span>
962967 </span>
963968 </NavLink>
969+ </div>
964970 </Hint>
965971 {/* A project's pages, in the order people use them. A page with more
966972 than one view shows them as tabs across its top. */}
+5−0
3737 const [open, setOpen] = useState(false);
3838 const touch = useRef(false);
3939 if (label == null || label === false || label === "") return children;
40+ // asChild merges className as a string, so a child whose className is a
41+ // function (NavLink's) would lose its classes: it gets a plain box instead.
42+ const functionClass = typeof (children.props as { className?: unknown }).className === "function";
4043 const trigger = disabled ? (
4144 <span tabIndex={0} className="inline-flex rounded-md outline-none focus-visible:ring-2 focus-visible:ring-accent *:pointer-events-none">
4245 {children}
4346 </span>
47+ ) : functionClass ? (
48+ <div>{children}</div>
4449 ) : (
4550 children
4651 );
+7−0
9292 assert.ok(!isStaff({ workspaces: [{ slug: "acme" }] }));
9393 assert.ok(!isStaff(null));
9494 });
95+
96+test("money under a hundredth of a cent reads $0.00, never $0.0000", () => {
97+ assert.equal(money(3), "$0.00");
98+ assert.equal(money(0), "$0.00");
99+ assert.equal(money(4_000), "$0.004");
100+ assert.equal(money(250), "$0.0003");
101+});
+2−1
172172 export function money(micros: number): string {
173173 const sign = micros < 0 ? "−" : "";
174174 const d = Math.abs(micros) / MICROS_PER_DOLLAR;
175− const digits = d === 0 || d >= 0.01 ? 2 : d >= 0.001 ? 3 : 4;
175+ // Under a hundredth of a cent there is nothing worth saying: "$0.00".
176+ const digits = d < 0.0001 || d >= 0.01 ? 2 : d >= 0.001 ? 3 : 4;
176177 return `${sign}$${d.toLocaleString("en-US", { minimumFractionDigits: digits, maximumFractionDigits: digits })}`;
177178 }
178179