Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion packages/app/src/app/blog/[slug]/og-image-render.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -102,6 +102,7 @@ export async function renderOgImage(meta: BlogPostMeta) {
<img
key={i}
src={tile.src}
alt=""
style={{
position: 'absolute',
left: 12 + col * 90,
Expand Down Expand Up @@ -180,7 +181,7 @@ export async function renderOgImage(meta: BlogPostMeta) {
timeZone: 'UTC',
})}
</span>
<img src={logoSrc} height={80} />
<img src={logoSrc} height={80} alt="SemiAnalysis" />
</div>
</div>
</div>,
Expand Down
1 change: 1 addition & 0 deletions packages/app/src/app/error.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ export default function Error({
<p className="text-lg mb-4">An unexpected error has occurred.</p>
<p className="text-md text-red-500 mb-8">{error.message}</p>
<button
type="button"
className="px-4 py-2 bg-primary text-primary-foreground rounded-md hover:bg-primary/90"
onClick={() => {
track('error_page_retry');
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -604,6 +604,7 @@ export default function ReplayPanel({
>
<span className="flex-1">MP4 export failed: {exportError}</span>
<button
type="button"
onClick={() => setExportError(null)}
className="text-destructive/70 hover:text-destructive cursor-pointer"
aria-label="Dismiss"
Expand Down
3 changes: 3 additions & 0 deletions packages/app/src/components/inference/ui/ChartDisplay.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,7 @@ function E2eXAxisDropdown({
<Popover open={open} onOpenChange={setOpen}>
<PopoverTrigger asChild>
<button
type="button"
className="inline-flex items-center gap-1 hover:opacity-70 transition-opacity cursor-pointer"
onClick={(e) => e.stopPropagation()}
>
Expand All @@ -86,6 +87,7 @@ function E2eXAxisDropdown({
<PopoverContent className="w-48 p-1" align="start">
{xAxisOptions.map((opt) => (
<button
type="button"
key={opt.label}
className={`w-full text-left px-3 py-1.5 text-sm rounded hover:bg-accent transition-colors ${
(opt.value === null && !selectedValue) || opt.value === selectedValue
Expand Down Expand Up @@ -680,6 +682,7 @@ export default function ChartDisplay() {
/>
{config.label}
<button
type="button"
className="ml-1 hover:opacity-70"
onClick={() => {
removeTrackedConfig(config.id);
Expand Down
69 changes: 48 additions & 21 deletions packages/app/src/components/submissions/SubmissionsTable.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,34 @@ function getModelDisplayName(dbModel: string): string {
return dbModel;
}

function SortHeader({
label,
field,
sortKey,
sortDir,
onSort,
}: {
label: string;
field: SortKey;
sortKey: SortKey;
sortDir: SortDir;
onSort: (field: SortKey) => void;
}) {
return (
<th
className="px-3 py-2 text-left text-xs font-medium text-muted-foreground cursor-pointer hover:text-foreground select-none"
onClick={() => onSort(field)}
>
<span className="flex items-center gap-1">
{label}
{sortKey === field && (
<span className="text-foreground">{sortDir === 'asc' ? '↑' : '↓'}</span>
)}
</span>
</th>
);
}

export default function SubmissionsTable({ data }: SubmissionsTableProps) {
const [sortKey, setSortKey] = useState<SortKey>('date');
const [sortDir, setSortDir] = useState<SortDir>('desc');
Expand Down Expand Up @@ -147,20 +175,6 @@ export default function SubmissionsTable({ data }: SubmissionsTableProps) {
});
}, []);

const SortHeader = ({ label, field }: { label: string; field: SortKey }) => (
<th
className="px-3 py-2 text-left text-xs font-medium text-muted-foreground cursor-pointer hover:text-foreground select-none"
onClick={() => handleSort(field)}
>
<span className="flex items-center gap-1">
{label}
{sortKey === field && (
<span className="text-foreground">{sortDir === 'asc' ? '↑' : '↓'}</span>
)}
</span>
</th>
);

return (
<div className="flex flex-col gap-3">
<input
Expand All @@ -178,13 +192,26 @@ export default function SubmissionsTable({ data }: SubmissionsTableProps) {
<thead className="bg-muted/50">
<tr>
<th className="w-8 px-2" />
<SortHeader label="GPU" field="hardware" />
<SortHeader label="Model" field="model" />
<SortHeader label="Precision" field="precision" />
<SortHeader label="Spec Method" field="spec_method" />
<SortHeader label="Framework" field="framework" />
<SortHeader label="Date" field="date" />
<SortHeader label="Datapoints" field="total_datapoints" />
{(
[
['GPU', 'hardware'],
['Model', 'model'],
['Precision', 'precision'],
['Spec Method', 'spec_method'],
['Framework', 'framework'],
['Date', 'date'],
['Datapoints', 'total_datapoints'],
] as [string, SortKey][]
).map(([label, field]) => (
<SortHeader
key={field}
label={label}
field={field}
sortKey={sortKey}
sortDir={sortDir}
onSort={handleSort}
/>
))}
<th
className="px-3 py-2 text-left text-xs font-medium text-muted-foreground select-none"
scope="col"
Expand Down
2 changes: 2 additions & 0 deletions packages/app/src/components/ui/bottom-toast.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,7 @@ export function BottomToast({
>
<div className="relative flex items-start gap-3 rounded-lg border border-border bg-card p-4 shadow-lg">
<button
type="button"
onClick={dismiss}
className="absolute top-2 right-2 text-muted-foreground hover:text-foreground transition-colors"
aria-label="Dismiss"
Expand All @@ -91,6 +92,7 @@ export function BottomToast({
<p className="text-xs text-muted-foreground">{description}</p>
{action && (
<button
type="button"
onClick={handleAction}
className="flex items-center gap-1.5 self-end px-3 py-1.5 rounded-md text-xs font-medium bg-primary text-primary-foreground hover:bg-primary/90 transition-colors"
>
Expand Down
1 change: 1 addition & 0 deletions packages/app/src/components/ui/calendar-picker-utils.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -280,6 +280,7 @@ export function CalendarMonthPanel({

return (
<button
type="button"
key={formatCalendarDate(day)}
onClick={() => !disabled && !isDisabled && onDateClick(day)}
onMouseEnter={() => !isDisabled && onDateHover?.(day)}
Expand Down
3 changes: 3 additions & 0 deletions packages/app/src/components/ui/chart-buttons.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -110,6 +110,7 @@ export function ChartButtons({
</PopoverTrigger>
<PopoverContent align="end" className="w-44 p-1">
<button
type="button"
data-testid="export-png-button"
data-ph-capture-attribute-export-type="png"
data-ph-capture-attribute-chart={chartId}
Expand All @@ -122,6 +123,7 @@ export function ChartButtons({
</button>
{onExportCsv && (
<button
type="button"
data-testid="export-csv-button"
data-ph-capture-attribute-export-type="csv"
data-ph-capture-attribute-chart={chartId}
Expand All @@ -134,6 +136,7 @@ export function ChartButtons({
)}
{onExportMp4 && (
<button
type="button"
data-testid="export-mp4-button"
data-ph-capture-attribute-export-type="mp4"
data-ph-capture-attribute-chart={chartId}
Expand Down
3 changes: 3 additions & 0 deletions packages/app/src/components/ui/chart-legend.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -237,6 +237,7 @@ export default function ChartLegend({
/>
{searchQuery && (
<button
type="button"
onClick={() => {
track('inference_legend_search_cleared');
setSearchQuery('');
Expand Down Expand Up @@ -283,6 +284,7 @@ export default function ChartLegend({
<div className="w-full no-export flex flex-wrap gap-x-3 gap-y-1">
{actions.map((action) => (
<button
type="button"
key={action.id}
data-testid={action.id}
onClick={action.onClick}
Expand Down Expand Up @@ -318,6 +320,7 @@ export default function ChartLegend({
const expandButton = hasLongText ? (
<div className="hidden lg:block mt-2 no-export">
<button
type="button"
onClick={handleLegendExpand}
className="text-xs text-accent-foreground hover:text-foreground flex items-center gap-1"
aria-label={isLegendExpanded ? 'Collapse legend' : 'Expand legend'}
Expand Down
3 changes: 3 additions & 0 deletions packages/app/src/components/ui/data-table.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -160,6 +160,7 @@ export function DataTable<T>({
/>
{search && (
<button
type="button"
onClick={() => {
setSearch('');
setPage(0);
Expand Down Expand Up @@ -286,6 +287,7 @@ export function DataTable<T>({
</div>
<div className="flex items-center gap-1">
<button
type="button"
onClick={() => {
setPage((p) => Math.max(0, p - 1));
track(`${analyticsPrefix}_page_changed`, { direction: 'prev' });
Expand All @@ -300,6 +302,7 @@ export function DataTable<T>({
{safePage + 1} / {totalPages}
</span>
<button
type="button"
onClick={() => {
setPage((p) => Math.min(totalPages - 1, p + 1));
track(`${analyticsPrefix}_page_changed`, { direction: 'next' });
Expand Down
1 change: 1 addition & 0 deletions packages/app/src/components/ui/multi-date-picker.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -179,6 +179,7 @@ export function MultiDatePicker({
>
{formatDisplayDate(dateStr)}
<button
type="button"
onClick={(e) => {
e.stopPropagation();
handleRemoveTempDate(dateStr);
Expand Down
3 changes: 3 additions & 0 deletions packages/app/src/components/ui/multi-select.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,7 @@ function MultiSelect({
}: MultiSelectProps) {
const [internalIsOpen, setInternalIsOpen] = React.useState(false);
const [search, setSearch] = React.useState('');
const listboxId = React.useId();
const searchStateRef = React.useRef(search);
searchStateRef.current = search;
const searchableRef = React.useRef(searchable);
Expand Down Expand Up @@ -245,6 +246,7 @@ function MultiSelect({
role="combobox"
aria-expanded={isOpen}
aria-haspopup="listbox"
aria-controls={listboxId}
Comment thread
functionstackx marked this conversation as resolved.
onClick={() => !disabled && setIsOpen(!isOpen)}
disabled={disabled}
data-slot="select-trigger"
Expand Down Expand Up @@ -327,6 +329,7 @@ function MultiSelect({
{isOpen && (
<div
ref={contentRef}
id={listboxId}
tabIndex={-1}
data-slot="select-content"
className={cn(
Expand Down
8 changes: 7 additions & 1 deletion packages/app/src/components/ui/searchable-select.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@ export function SearchableSelect({
}: SearchableSelectProps) {
const [isOpen, setIsOpen] = React.useState(false);
const [search, setSearch] = React.useState('');
const listboxId = React.useId();
// Defer the trigger label until the component has mounted on the client.
// The selected value derives from URL params / persisted state which only
// resolve client-side, so SSR would otherwise lock in the default label and
Expand Down Expand Up @@ -125,6 +126,7 @@ export function SearchableSelect({
role="combobox"
aria-expanded={isOpen}
aria-haspopup="listbox"
aria-controls={listboxId}
onClick={() => !disabled && setIsOpen(!isOpen)}
disabled={disabled}
className={cn(
Expand Down Expand Up @@ -188,7 +190,11 @@ export function SearchableSelect({
)}
</div>
)}
<div className="p-1 max-h-72 overflow-y-auto custom-scrollbar">
<div
id={listboxId}
role="listbox"
className="p-1 max-h-72 overflow-y-auto custom-scrollbar"
>
{filteredGroups.length === 0 && (
<div className="text-muted-foreground px-2 py-1.5 text-sm text-center">
No results
Expand Down
2 changes: 2 additions & 0 deletions packages/app/src/components/ui/unofficial-banner.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,7 @@ export function UnofficialBanner({ runs, onDismissRun, onDismissAll }: Unofficia
</div>
{multiple && onDismissAll && (
<button
type="button"
onClick={() => {
track('unofficial_banner_dismissed_all', { count: runs.length });
onDismissAll();
Expand Down Expand Up @@ -107,6 +108,7 @@ function RunChip({
</a>
{onDismiss && (
<button
type="button"
onClick={() => {
track('unofficial_banner_run_dismissed', { branch: run.branch });
onDismiss();
Expand Down
Loading