98 lines
2.1 KiB
TypeScript
98 lines
2.1 KiB
TypeScript
/**
|
|||
|
|
* Small shared pieces for the compare sections: the section shell, the
|
||
|
|
* row-label + per-school-cell grid, and tone-mapped chips. Copy passed into
|
||
|
|
* these comes verbatim from the reviewed mockups
|
||
|
|
* (docs/superpowers/specs/mockups/) — do not paraphrase it here.
|
||
|
|
*/
|
||
|
|
|
||
|
|
'use client';
|
||
|
|
|
||
|
|
import type { CSSProperties, ReactNode } from 'react';
|
||
|
|
|
||
|
|
import type { School } from '@/lib/types';
|
||
|
|
import { CHART_TEXT_COLORS } from '@/lib/utils';
|
||
|
|
import styles from './compareSections.module.css';
|
||
|
|
|
||
|
|
export function Section({
|
||
|
|
title,
|
||
|
|
how,
|
||
|
|
children,
|
||
|
|
}: {
|
||
|
|
title: string;
|
||
|
|
how?: ReactNode;
|
||
|
|
children: ReactNode;
|
||
|
|
}) {
|
||
|
|
return (
|
||
|
|
<section className={styles.section}>
|
||
|
|
<h2 className={styles.sectionTitle}>{title}</h2>
|
||
|
|
{how && <p className={styles.how}>{how}</p>}
|
||
|
|
{children}
|
||
|
|
</section>
|
||
|
|
);
|
||
|
|
}
|
||
|
|
|
||
|
|
export function SectionGrid({
|
||
|
|
schools,
|
||
|
|
children,
|
||
|
|
}: {
|
||
|
|
schools: School[];
|
||
|
|
children: ReactNode;
|
||
|
|
}) {
|
||
|
|
return (
|
||
|
|
<div
|
||
|
|
className={styles.grid}
|
||
|
|
style={{ '--school-count': schools.length } as CSSProperties}
|
||
|
|
>
|
||
|
|
{children}
|
||
|
|
</div>
|
||
|
|
);
|
||
|
|
}
|
||
|
|
|
||
|
|
export function RowLabel({ children, tip }: { children: ReactNode; tip?: string }) {
|
||
|
|
return (
|
||
|
|
<div className={styles.rowLabel}>
|
||
|
|
{children}
|
||
|
|
{tip && (
|
||
|
|
<span className={styles.help} title={tip} aria-label={tip}>
|
||
|
|
?
|
||
|
|
</span>
|
||
|
|
)}
|
||
|
|
</div>
|
||
|
|
);
|
||
|
|
}
|
||
|
|
|
||
|
|
export function Cell({
|
||
|
|
school,
|
||
|
|
index,
|
||
|
|
children,
|
||
|
|
}: {
|
||
|
|
school: School;
|
||
|
|
index: number;
|
||
|
|
children: ReactNode;
|
||
|
|
}) {
|
||
|
|
return (
|
||
|
|
<div
|
||
|
|
className={styles.cell}
|
||
|
|
data-school={school.school_name}
|
||
|
|
style={{ '--sc': CHART_TEXT_COLORS[index % CHART_TEXT_COLORS.length] } as CSSProperties}
|
||
|
|
>
|
||
|
|
{children}
|
||
|
|
</div>
|
||
|
|
);
|
||
|
|
}
|
||
|
|
|
||
|
|
export type ChipTone = 'good' | 'warn' | 'bad' | 'neutral';
|
||
|
|
|
||
|
|
const CHIP_TONE_CLASS: Record<ChipTone, string> = {
|
||
|
|
good: styles.chipGood,
|
||
|
|
warn: styles.chipWarn,
|
||
|
|
bad: styles.chipBad,
|
||
|
|
neutral: styles.chipNeutral,
|
||
|
|
};
|
||
|
|
|
||
|
|
export function Chip({ tone, children }: { tone: ChipTone; children: ReactNode }) {
|
||
|
|
return <span className={`${styles.chip} ${CHIP_TONE_CLASS[tone]}`}>{children}</span>;
|
||
|
|
}
|
||
|
|
|
||
|
|
export const sectionStyles = styles;
|