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
59 changes: 50 additions & 9 deletions apps/ui/src/components/MeasurementDashboard.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -25,18 +25,57 @@ import { MiniHeatmap } from './MiniHeatmap';
import { ConfidenceBandBadge } from './sessionMusician/ConfidenceBandBadge';
import { MixDoctorPanel } from './MixDoctorPanel';
import {
Button,
DataTable,
DeltaBadge,
OutlinePillButton,
StatusBadge,
DeviceRack,
EmptyState,
MetricBar,
MetricBarRow,
MetricTile,
Pill,
TokenBadgeList,
} from './MeasurementPrimitives';
import { DataTable, DeviceRack, EmptyState, MetricBar, MetricBarRow, MetricTile } from './ui';
type Tone,
} from './ui';
import { Sparkline } from './Sparkline';
import { SpectralCursorProvider } from '../hooks/useSpectralCursorBus';
import { formatDisplayText, getTextRoleClassName } from '../utils/displayText';
import { HarmonyLanes } from './HarmonyLanes';
import { StructureLanes } from './StructureLanes';

// Local adapter over the canonical ui/Pill. The dashboard's detail rows use a
// compact label/tone/compact status chip in ~17 places (and chordToneForLabel
// still emits the legacy off-palette tones); this maps those onto the token
// palette in one spot so the call sites stay untouched ahead of the Phase 5
// split. Not a competing primitive — just local sugar over Pill.
type LegacyBadgeTone = Tone | 'muted' | 'info' | 'violet';
const PILL_TONE_FOR_LEGACY: Record<LegacyBadgeTone, Tone> = {
accent: 'accent',
success: 'success',
warning: 'warning',
error: 'error',
neutral: 'neutral',
muted: 'neutral',
info: 'neutral',
violet: 'neutral',
};

function StatusBadge({
label,
tone = 'neutral',
compact = false,
}: {
label: React.ReactNode;
tone?: LegacyBadgeTone;
compact?: boolean;
}) {
return (
<Pill tone={PILL_TONE_FOR_LEGACY[tone]} size={compact ? 'xs' : 'sm'}>
{label}
</Pill>
);
}

interface MeasurementDashboardProps {
phase1: Phase1Result;
spectralArtifacts?: SpectralArtifacts | null;
Expand Down Expand Up @@ -1457,7 +1496,7 @@ export function MeasurementDashboard({
items={[
{ label: phase1.genreDetail.genreFamily, tone: 'accent' },
...(phase1.genreDetail.secondaryGenre
? [{ label: phase1.genreDetail.secondaryGenre, tone: 'muted' as const }]
? [{ label: phase1.genreDetail.secondaryGenre, tone: 'neutral' as const }]
: []),
]}
/>
Expand Down Expand Up @@ -2026,12 +2065,14 @@ export function MeasurementDashboard({
</React.Fragment>
) : (
<React.Fragment key={kind}>
<OutlinePillButton
<Button
variant="secondary"
size="sm"
onClick={() => handleGenerate(kind)}
disabled={generating.has(kind)}
tone="accent"
label={generating.has(kind) ? `${label}...` : `Generate ${label}`}
/>
>
{generating.has(kind) ? `${label}...` : `Generate ${label}`}
</Button>
</React.Fragment>
),
)}
Expand Down
26 changes: 26 additions & 0 deletions apps/ui/src/components/ui/DeltaBadge.stories.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
import React from 'react';
import type { Meta, StoryObj } from '@storybook/react-vite';

import { DeltaBadge } from './DeltaBadge';

const meta: Meta<typeof DeltaBadge> = {
title: 'UI/DeltaBadge',
component: DeltaBadge,
args: { value: -1.8, unit: 'dB', okThreshold: 0.5, warnThreshold: 1.5 },
};

export default meta;
type Story = StoryObj<typeof DeltaBadge>;

export const Default: Story = {};

export const ThresholdLadder: Story = {
render: () => (
<div className="flex gap-2 flex-wrap">
<DeltaBadge value={0.3} unit="dB" okThreshold={0.5} warnThreshold={1.5} />
<DeltaBadge value={1.1} unit="dB" okThreshold={0.5} warnThreshold={1.5} />
<DeltaBadge value={4.2} unit="dB" okThreshold={0.5} warnThreshold={1.5} />
<DeltaBadge value={null} unit="dB" okThreshold={0.5} warnThreshold={1.5} />
</div>
),
};
34 changes: 34 additions & 0 deletions apps/ui/src/components/ui/TokenBadgeList.stories.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
import React from 'react';
import type { Meta, StoryObj } from '@storybook/react-vite';

import { TokenBadgeList } from './TokenBadgeList';

const meta: Meta<typeof TokenBadgeList> = {
title: 'UI/TokenBadgeList',
component: TokenBadgeList,
args: {
items: [
{ label: 'house', tone: 'accent' },
{ label: 'techno', tone: 'neutral' },
],
},
};

export default meta;
type Story = StoryObj<typeof TokenBadgeList>;

export const Default: Story = {};

export const Tones: Story = {
render: () => (
<TokenBadgeList
items={[
{ label: 'accent', tone: 'accent' },
{ label: 'success', tone: 'success' },
{ label: 'warning', tone: 'warning' },
{ label: 'error', tone: 'error' },
{ label: 'neutral', tone: 'neutral' },
]}
/>
),
};
Loading