refactor(ui): extract reusable component package
This commit is contained in:
parent
87261b5a3f
commit
2664804e91
86 changed files with 102 additions and 85 deletions
16
packages/ui/src/stories/Badge.stories.tsx
Normal file
16
packages/ui/src/stories/Badge.stories.tsx
Normal file
|
|
@ -0,0 +1,16 @@
|
|||
import type { Meta, StoryObj } from "@storybook/react-vite";
|
||||
import { Badge } from "../components/Badge";
|
||||
|
||||
const meta = {
|
||||
title: "UI/Badge",
|
||||
component: Badge,
|
||||
args: {
|
||||
label: "Ready",
|
||||
severity: "ok",
|
||||
},
|
||||
} satisfies Meta<typeof Badge>;
|
||||
|
||||
export default meta;
|
||||
type Story = StoryObj<typeof meta>;
|
||||
|
||||
export const Default: Story = {};
|
||||
21
packages/ui/src/stories/Button.stories.tsx
Normal file
21
packages/ui/src/stories/Button.stories.tsx
Normal file
|
|
@ -0,0 +1,21 @@
|
|||
import type { Meta, StoryObj } from "@storybook/react-vite";
|
||||
import { Button } from "../components/Button";
|
||||
|
||||
const meta = {
|
||||
title: "UI/Button",
|
||||
component: Button,
|
||||
args: {
|
||||
label: "Refresh",
|
||||
icon: "mdi:refresh",
|
||||
},
|
||||
} satisfies Meta<typeof Button>;
|
||||
|
||||
export default meta;
|
||||
type Story = StoryObj<typeof meta>;
|
||||
|
||||
export const Primary: Story = {};
|
||||
export const Secondary: Story = {
|
||||
args: {
|
||||
variant: "secondary",
|
||||
},
|
||||
};
|
||||
16
packages/ui/src/stories/CornerBracketFrame.stories.tsx
Normal file
16
packages/ui/src/stories/CornerBracketFrame.stories.tsx
Normal file
|
|
@ -0,0 +1,16 @@
|
|||
import type { Meta, StoryObj } from "@storybook/react-vite";
|
||||
import { CornerBracketFrame } from "../components/CornerBracketFrame";
|
||||
|
||||
const meta = {
|
||||
title: "UI/CornerBracketFrame",
|
||||
component: CornerBracketFrame,
|
||||
args: {
|
||||
tone: "accent",
|
||||
size: "md",
|
||||
},
|
||||
} satisfies Meta<typeof CornerBracketFrame>;
|
||||
|
||||
export default meta;
|
||||
type Story = StoryObj<typeof meta>;
|
||||
|
||||
export const Default: Story = {};
|
||||
21
packages/ui/src/stories/DashboardFrame.stories.tsx
Normal file
21
packages/ui/src/stories/DashboardFrame.stories.tsx
Normal file
|
|
@ -0,0 +1,21 @@
|
|||
import type { Meta, StoryObj } from "@storybook/react-vite";
|
||||
import { DashboardFrame } from "../components/DashboardFrame";
|
||||
import { fullCompositionDashboard, secondaryDashboard } from "./story-data";
|
||||
|
||||
const meta = {
|
||||
title: "UI/DashboardFrame",
|
||||
component: DashboardFrame,
|
||||
args: {
|
||||
dashboard: fullCompositionDashboard,
|
||||
},
|
||||
} satisfies Meta<typeof DashboardFrame>;
|
||||
|
||||
export default meta;
|
||||
type Story = StoryObj<typeof meta>;
|
||||
|
||||
export const FullComposition: Story = {};
|
||||
export const Secondary: Story = {
|
||||
args: {
|
||||
dashboard: secondaryDashboard,
|
||||
},
|
||||
};
|
||||
19
packages/ui/src/stories/DashboardHeader.stories.tsx
Normal file
19
packages/ui/src/stories/DashboardHeader.stories.tsx
Normal file
|
|
@ -0,0 +1,19 @@
|
|||
import type { Meta, StoryObj } from "@storybook/react-vite";
|
||||
import { DashboardHeader } from "../components/DashboardHeader";
|
||||
import { moduleBlocks } from "./story-data";
|
||||
|
||||
const meta = {
|
||||
title: "UI/DashboardHeader",
|
||||
component: DashboardHeader,
|
||||
args: {
|
||||
eyebrow: "Preview Surface",
|
||||
title: "Operations Console",
|
||||
subtitle: "Generic dashboard header",
|
||||
module: moduleBlocks.compact,
|
||||
},
|
||||
} satisfies Meta<typeof DashboardHeader>;
|
||||
|
||||
export default meta;
|
||||
type Story = StoryObj<typeof meta>;
|
||||
|
||||
export const WithModule: Story = {};
|
||||
16
packages/ui/src/stories/DashboardOnePager.stories.tsx
Normal file
16
packages/ui/src/stories/DashboardOnePager.stories.tsx
Normal file
|
|
@ -0,0 +1,16 @@
|
|||
import type { Meta, StoryObj } from "@storybook/react-vite";
|
||||
import { DashboardFrame } from "../components/DashboardFrame";
|
||||
import { fullCompositionDashboard } from "./story-data";
|
||||
|
||||
const meta = {
|
||||
title: "UI/DashboardOnePager",
|
||||
component: DashboardFrame,
|
||||
args: {
|
||||
dashboard: fullCompositionDashboard,
|
||||
},
|
||||
} satisfies Meta<typeof DashboardFrame>;
|
||||
|
||||
export default meta;
|
||||
type Story = StoryObj<typeof meta>;
|
||||
|
||||
export const OnePager: Story = {};
|
||||
16
packages/ui/src/stories/DiagonalStripeField.stories.tsx
Normal file
16
packages/ui/src/stories/DiagonalStripeField.stories.tsx
Normal file
|
|
@ -0,0 +1,16 @@
|
|||
import type { Meta, StoryObj } from "@storybook/react-vite";
|
||||
import { DiagonalStripeField } from "../components/DiagonalStripeField";
|
||||
|
||||
const meta = {
|
||||
title: "UI/DiagonalStripeField",
|
||||
component: DiagonalStripeField,
|
||||
args: {
|
||||
tone: "accent",
|
||||
density: "regular",
|
||||
},
|
||||
} satisfies Meta<typeof DiagonalStripeField>;
|
||||
|
||||
export default meta;
|
||||
type Story = StoryObj<typeof meta>;
|
||||
|
||||
export const Default: Story = {};
|
||||
21
packages/ui/src/stories/FooterCell.stories.tsx
Normal file
21
packages/ui/src/stories/FooterCell.stories.tsx
Normal file
|
|
@ -0,0 +1,21 @@
|
|||
import type { Meta, StoryObj } from "@storybook/react-vite";
|
||||
import { FooterCell } from "../components/FooterCell";
|
||||
import { statusItems } from "./story-data";
|
||||
|
||||
const meta = {
|
||||
title: "UI/FooterCell",
|
||||
component: FooterCell,
|
||||
args: {
|
||||
item: statusItems.ok,
|
||||
},
|
||||
} satisfies Meta<typeof FooterCell>;
|
||||
|
||||
export default meta;
|
||||
type Story = StoryObj<typeof meta>;
|
||||
|
||||
export const Operational: Story = {};
|
||||
export const Linked: Story = {
|
||||
args: {
|
||||
item: statusItems.action,
|
||||
},
|
||||
};
|
||||
16
packages/ui/src/stories/FooterStatusCell.stories.tsx
Normal file
16
packages/ui/src/stories/FooterStatusCell.stories.tsx
Normal file
|
|
@ -0,0 +1,16 @@
|
|||
import type { Meta, StoryObj } from "@storybook/react-vite";
|
||||
import { FooterStatusCell } from "../components/FooterStatusCell";
|
||||
import { statusItems } from "./story-data";
|
||||
|
||||
const meta = {
|
||||
title: "UI/FooterStatusCell",
|
||||
component: FooterStatusCell,
|
||||
args: {
|
||||
item: statusItems.degraded,
|
||||
},
|
||||
} satisfies Meta<typeof FooterStatusCell>;
|
||||
|
||||
export default meta;
|
||||
type Story = StoryObj<typeof meta>;
|
||||
|
||||
export const Warning: Story = {};
|
||||
25
packages/ui/src/stories/GridFrame.stories.tsx
Normal file
25
packages/ui/src/stories/GridFrame.stories.tsx
Normal file
|
|
@ -0,0 +1,25 @@
|
|||
import type { Meta, StoryObj } from "@storybook/react-vite";
|
||||
import { GridFrame } from "../components/GridFrame";
|
||||
import { ModuleCard } from "../components/ModuleCard";
|
||||
import { moduleBlocks } from "./story-data";
|
||||
|
||||
const meta = {
|
||||
title: "UI/GridFrame",
|
||||
component: GridFrame,
|
||||
render: (args) => (
|
||||
<GridFrame {...args}>
|
||||
<ModuleCard module={moduleBlocks.compact} />
|
||||
<ModuleCard module={moduleBlocks.unavailable} />
|
||||
<ModuleCard module={moduleBlocks.long} />
|
||||
</GridFrame>
|
||||
),
|
||||
} satisfies Meta<typeof GridFrame>;
|
||||
|
||||
export default meta;
|
||||
type Story = StoryObj<typeof meta>;
|
||||
|
||||
export const Dense: Story = {
|
||||
args: {
|
||||
density: "dense",
|
||||
},
|
||||
};
|
||||
16
packages/ui/src/stories/IconButton.stories.tsx
Normal file
16
packages/ui/src/stories/IconButton.stories.tsx
Normal file
|
|
@ -0,0 +1,16 @@
|
|||
import type { Meta, StoryObj } from "@storybook/react-vite";
|
||||
import { IconButton } from "../components/IconButton";
|
||||
|
||||
const meta = {
|
||||
title: "UI/IconButton",
|
||||
component: IconButton,
|
||||
args: {
|
||||
icon: "mdi:refresh",
|
||||
label: "Refresh status",
|
||||
},
|
||||
} satisfies Meta<typeof IconButton>;
|
||||
|
||||
export default meta;
|
||||
type Story = StoryObj<typeof meta>;
|
||||
|
||||
export const Default: Story = {};
|
||||
17
packages/ui/src/stories/IconGlyph.stories.tsx
Normal file
17
packages/ui/src/stories/IconGlyph.stories.tsx
Normal file
|
|
@ -0,0 +1,17 @@
|
|||
import type { Meta, StoryObj } from "@storybook/react-vite";
|
||||
import { IconGlyph } from "../components/IconGlyph";
|
||||
|
||||
const meta = {
|
||||
title: "UI/IconGlyph",
|
||||
component: IconGlyph,
|
||||
args: {
|
||||
name: "mdi:server-network",
|
||||
label: "Generic service",
|
||||
size: "md",
|
||||
},
|
||||
} satisfies Meta<typeof IconGlyph>;
|
||||
|
||||
export default meta;
|
||||
type Story = StoryObj<typeof meta>;
|
||||
|
||||
export const Default: Story = {};
|
||||
17
packages/ui/src/stories/LineChart.stories.tsx
Normal file
17
packages/ui/src/stories/LineChart.stories.tsx
Normal file
|
|
@ -0,0 +1,17 @@
|
|||
import type { Meta, StoryObj } from "@storybook/react-vite";
|
||||
import { LineChart } from "../components/LineChart";
|
||||
|
||||
const meta = {
|
||||
title: "UI/LineChart",
|
||||
component: LineChart,
|
||||
args: {
|
||||
values: [12, 18, 24, 20, 36, 44],
|
||||
severity: "ok",
|
||||
label: "Generic trend",
|
||||
},
|
||||
} satisfies Meta<typeof LineChart>;
|
||||
|
||||
export default meta;
|
||||
type Story = StoryObj<typeof meta>;
|
||||
|
||||
export const Trend: Story = {};
|
||||
21
packages/ui/src/stories/ModuleCard.stories.tsx
Normal file
21
packages/ui/src/stories/ModuleCard.stories.tsx
Normal file
|
|
@ -0,0 +1,21 @@
|
|||
import type { Meta, StoryObj } from "@storybook/react-vite";
|
||||
import { ModuleCard } from "../components/ModuleCard";
|
||||
import { moduleBlocks } from "./story-data";
|
||||
|
||||
const meta = {
|
||||
title: "UI/ModuleCard",
|
||||
component: ModuleCard,
|
||||
args: {
|
||||
module: moduleBlocks.compact,
|
||||
},
|
||||
} satisfies Meta<typeof ModuleCard>;
|
||||
|
||||
export default meta;
|
||||
type Story = StoryObj<typeof meta>;
|
||||
|
||||
export const Compact: Story = {};
|
||||
export const Long: Story = {
|
||||
args: {
|
||||
module: moduleBlocks.long,
|
||||
},
|
||||
};
|
||||
23
packages/ui/src/stories/Panel.stories.tsx
Normal file
23
packages/ui/src/stories/Panel.stories.tsx
Normal file
|
|
@ -0,0 +1,23 @@
|
|||
import type { Meta, StoryObj } from "@storybook/react-vite";
|
||||
import { Panel } from "../components/Panel";
|
||||
import { ServiceRow } from "../components/ServiceRow";
|
||||
import { serviceRows } from "./story-data";
|
||||
|
||||
const meta = {
|
||||
title: "UI/Panel",
|
||||
component: Panel,
|
||||
render: (args) => (
|
||||
<Panel {...args}>
|
||||
<ServiceRow service={serviceRows.normal} />
|
||||
<ServiceRow service={serviceRows.degraded} />
|
||||
</Panel>
|
||||
),
|
||||
args: {
|
||||
title: "Generic Panel",
|
||||
},
|
||||
} satisfies Meta<typeof Panel>;
|
||||
|
||||
export default meta;
|
||||
type Story = StoryObj<typeof meta>;
|
||||
|
||||
export const Dense: Story = {};
|
||||
17
packages/ui/src/stories/ProgressMeter.stories.tsx
Normal file
17
packages/ui/src/stories/ProgressMeter.stories.tsx
Normal file
|
|
@ -0,0 +1,17 @@
|
|||
import type { Meta, StoryObj } from "@storybook/react-vite";
|
||||
import { ProgressMeter } from "../components/ProgressMeter";
|
||||
|
||||
const meta = {
|
||||
title: "UI/ProgressMeter",
|
||||
component: ProgressMeter,
|
||||
args: {
|
||||
value: 72,
|
||||
severity: "ok",
|
||||
label: "Capacity",
|
||||
},
|
||||
} satisfies Meta<typeof ProgressMeter>;
|
||||
|
||||
export default meta;
|
||||
type Story = StoryObj<typeof meta>;
|
||||
|
||||
export const Filled: Story = {};
|
||||
16
packages/ui/src/stories/ScanlineField.stories.tsx
Normal file
16
packages/ui/src/stories/ScanlineField.stories.tsx
Normal file
|
|
@ -0,0 +1,16 @@
|
|||
import type { Meta, StoryObj } from "@storybook/react-vite";
|
||||
import { ScanlineField } from "../components/ScanlineField";
|
||||
|
||||
const meta = {
|
||||
title: "UI/ScanlineField",
|
||||
component: ScanlineField,
|
||||
args: {
|
||||
tone: "accent",
|
||||
intensity: "medium",
|
||||
},
|
||||
} satisfies Meta<typeof ScanlineField>;
|
||||
|
||||
export default meta;
|
||||
type Story = StoryObj<typeof meta>;
|
||||
|
||||
export const Default: Story = {};
|
||||
15
packages/ui/src/stories/Separator.stories.tsx
Normal file
15
packages/ui/src/stories/Separator.stories.tsx
Normal file
|
|
@ -0,0 +1,15 @@
|
|||
import type { Meta, StoryObj } from "@storybook/react-vite";
|
||||
import { Separator } from "../components/Separator";
|
||||
|
||||
const meta = {
|
||||
title: "UI/Separator",
|
||||
component: Separator,
|
||||
args: {
|
||||
orientation: "horizontal",
|
||||
},
|
||||
} satisfies Meta<typeof Separator>;
|
||||
|
||||
export default meta;
|
||||
type Story = StoryObj<typeof meta>;
|
||||
|
||||
export const Horizontal: Story = {};
|
||||
16
packages/ui/src/stories/ServiceGroupPanel.stories.tsx
Normal file
16
packages/ui/src/stories/ServiceGroupPanel.stories.tsx
Normal file
|
|
@ -0,0 +1,16 @@
|
|||
import type { Meta, StoryObj } from "@storybook/react-vite";
|
||||
import { ServiceGroupPanel } from "../components/ServiceGroupPanel";
|
||||
import { serviceGroups } from "./story-data";
|
||||
|
||||
const meta = {
|
||||
title: "UI/ServiceGroupPanel",
|
||||
component: ServiceGroupPanel,
|
||||
args: {
|
||||
group: serviceGroups.mixed,
|
||||
},
|
||||
} satisfies Meta<typeof ServiceGroupPanel>;
|
||||
|
||||
export default meta;
|
||||
type Story = StoryObj<typeof meta>;
|
||||
|
||||
export const Mixed: Story = {};
|
||||
16
packages/ui/src/stories/ServicePanel.stories.tsx
Normal file
16
packages/ui/src/stories/ServicePanel.stories.tsx
Normal file
|
|
@ -0,0 +1,16 @@
|
|||
import type { Meta, StoryObj } from "@storybook/react-vite";
|
||||
import { ServicePanel } from "../components/ServicePanel";
|
||||
import { serviceGroups } from "./story-data";
|
||||
|
||||
const meta = {
|
||||
title: "UI/ServicePanel",
|
||||
component: ServicePanel,
|
||||
args: {
|
||||
group: serviceGroups.long,
|
||||
},
|
||||
} satisfies Meta<typeof ServicePanel>;
|
||||
|
||||
export default meta;
|
||||
type Story = StoryObj<typeof meta>;
|
||||
|
||||
export const LongList: Story = {};
|
||||
21
packages/ui/src/stories/ServiceRow.stories.tsx
Normal file
21
packages/ui/src/stories/ServiceRow.stories.tsx
Normal file
|
|
@ -0,0 +1,21 @@
|
|||
import type { Meta, StoryObj } from "@storybook/react-vite";
|
||||
import { ServiceRow } from "../components/ServiceRow";
|
||||
import { serviceRows } from "./story-data";
|
||||
|
||||
const meta = {
|
||||
title: "UI/ServiceRow",
|
||||
component: ServiceRow,
|
||||
args: {
|
||||
service: serviceRows.normal,
|
||||
},
|
||||
} satisfies Meta<typeof ServiceRow>;
|
||||
|
||||
export default meta;
|
||||
type Story = StoryObj<typeof meta>;
|
||||
|
||||
export const Normal: Story = {};
|
||||
export const Warning: Story = {
|
||||
args: {
|
||||
service: serviceRows.degraded,
|
||||
},
|
||||
};
|
||||
16
packages/ui/src/stories/SignalTrace.stories.tsx
Normal file
16
packages/ui/src/stories/SignalTrace.stories.tsx
Normal file
|
|
@ -0,0 +1,16 @@
|
|||
import type { Meta, StoryObj } from "@storybook/react-vite";
|
||||
import { SignalTrace } from "../components/SignalTrace";
|
||||
|
||||
const meta = {
|
||||
title: "UI/SignalTrace",
|
||||
component: SignalTrace,
|
||||
args: {
|
||||
tone: "accent",
|
||||
orientation: "horizontal",
|
||||
},
|
||||
} satisfies Meta<typeof SignalTrace>;
|
||||
|
||||
export default meta;
|
||||
type Story = StoryObj<typeof meta>;
|
||||
|
||||
export const Horizontal: Story = {};
|
||||
16
packages/ui/src/stories/Sparkline.stories.tsx
Normal file
16
packages/ui/src/stories/Sparkline.stories.tsx
Normal file
|
|
@ -0,0 +1,16 @@
|
|||
import type { Meta, StoryObj } from "@storybook/react-vite";
|
||||
import { Sparkline } from "../components/Sparkline";
|
||||
|
||||
const meta = {
|
||||
title: "UI/Sparkline",
|
||||
component: Sparkline,
|
||||
args: {
|
||||
values: [8, 14, 12, 24, 18, 30],
|
||||
severity: "ok",
|
||||
},
|
||||
} satisfies Meta<typeof Sparkline>;
|
||||
|
||||
export default meta;
|
||||
type Story = StoryObj<typeof meta>;
|
||||
|
||||
export const Default: Story = {};
|
||||
16
packages/ui/src/stories/StatusBadge.stories.tsx
Normal file
16
packages/ui/src/stories/StatusBadge.stories.tsx
Normal file
|
|
@ -0,0 +1,16 @@
|
|||
import type { Meta, StoryObj } from "@storybook/react-vite";
|
||||
import { StatusBadge } from "../components/StatusBadge";
|
||||
|
||||
const meta = {
|
||||
title: "UI/StatusBadge",
|
||||
component: StatusBadge,
|
||||
args: {
|
||||
label: "Ready",
|
||||
severity: "ok",
|
||||
},
|
||||
} satisfies Meta<typeof StatusBadge>;
|
||||
|
||||
export default meta;
|
||||
type Story = StoryObj<typeof meta>;
|
||||
|
||||
export const Ready: Story = {};
|
||||
17
packages/ui/src/stories/StatusStrip.stories.tsx
Normal file
17
packages/ui/src/stories/StatusStrip.stories.tsx
Normal file
|
|
@ -0,0 +1,17 @@
|
|||
import type { Meta, StoryObj } from "@storybook/react-vite";
|
||||
import { StatusStrip } from "../components/StatusStrip";
|
||||
import { mixedStatusStrip } from "./story-data";
|
||||
|
||||
const meta = {
|
||||
title: "UI/StatusStrip",
|
||||
component: StatusStrip,
|
||||
args: {
|
||||
id: "generic-status",
|
||||
items: mixedStatusStrip,
|
||||
},
|
||||
} satisfies Meta<typeof StatusStrip>;
|
||||
|
||||
export default meta;
|
||||
type Story = StoryObj<typeof meta>;
|
||||
|
||||
export const Mixed: Story = {};
|
||||
18
packages/ui/src/stories/SystemState.stories.tsx
Normal file
18
packages/ui/src/stories/SystemState.stories.tsx
Normal file
|
|
@ -0,0 +1,18 @@
|
|||
import type { Meta, StoryObj } from "@storybook/react-vite";
|
||||
import { SystemState } from "../components/SystemState";
|
||||
|
||||
const meta = {
|
||||
title: "UI/SystemState",
|
||||
component: SystemState,
|
||||
args: {
|
||||
title: "Loading Dashboard",
|
||||
detail: "Fetching active model",
|
||||
severity: "loading",
|
||||
icon: "mdi:progress-clock",
|
||||
},
|
||||
} satisfies Meta<typeof SystemState>;
|
||||
|
||||
export default meta;
|
||||
type Story = StoryObj<typeof meta>;
|
||||
|
||||
export const Loading: Story = {};
|
||||
21
packages/ui/src/stories/TelemetryCard.stories.tsx
Normal file
21
packages/ui/src/stories/TelemetryCard.stories.tsx
Normal file
|
|
@ -0,0 +1,21 @@
|
|||
import type { Meta, StoryObj } from "@storybook/react-vite";
|
||||
import { TelemetryCard } from "../components/TelemetryCard";
|
||||
import { telemetryCards } from "./story-data";
|
||||
|
||||
const meta = {
|
||||
title: "UI/TelemetryCard",
|
||||
component: TelemetryCard,
|
||||
args: {
|
||||
card: telemetryCards.percent,
|
||||
},
|
||||
} satisfies Meta<typeof TelemetryCard>;
|
||||
|
||||
export default meta;
|
||||
type Story = StoryObj<typeof meta>;
|
||||
|
||||
export const Percent: Story = {};
|
||||
export const Danger: Story = {
|
||||
args: {
|
||||
card: telemetryCards.danger,
|
||||
},
|
||||
};
|
||||
21
packages/ui/src/stories/TelemetryGrid.stories.tsx
Normal file
21
packages/ui/src/stories/TelemetryGrid.stories.tsx
Normal file
|
|
@ -0,0 +1,21 @@
|
|||
import type { Meta, StoryObj } from "@storybook/react-vite";
|
||||
import { TelemetryGrid } from "../components/TelemetryGrid";
|
||||
import { eightTelemetryCards, sixteenTelemetryCards } from "./story-data";
|
||||
|
||||
const meta = {
|
||||
title: "UI/TelemetryGrid",
|
||||
component: TelemetryGrid,
|
||||
args: {
|
||||
cards: eightTelemetryCards,
|
||||
},
|
||||
} satisfies Meta<typeof TelemetryGrid>;
|
||||
|
||||
export default meta;
|
||||
type Story = StoryObj<typeof meta>;
|
||||
|
||||
export const EightCards: Story = {};
|
||||
export const SixteenCards: Story = {
|
||||
args: {
|
||||
cards: sixteenTelemetryCards,
|
||||
},
|
||||
};
|
||||
16
packages/ui/src/stories/TelemetryStrip.stories.tsx
Normal file
16
packages/ui/src/stories/TelemetryStrip.stories.tsx
Normal file
|
|
@ -0,0 +1,16 @@
|
|||
import type { Meta, StoryObj } from "@storybook/react-vite";
|
||||
import { TelemetryStrip } from "../components/TelemetryStrip";
|
||||
import { eightTelemetryCards } from "./story-data";
|
||||
|
||||
const meta = {
|
||||
title: "UI/TelemetryStrip",
|
||||
component: TelemetryStrip,
|
||||
args: {
|
||||
cards: eightTelemetryCards,
|
||||
},
|
||||
} satisfies Meta<typeof TelemetryStrip>;
|
||||
|
||||
export default meta;
|
||||
type Story = StoryObj<typeof meta>;
|
||||
|
||||
export const Default: Story = {};
|
||||
26
packages/ui/src/stories/ThemeToggle.stories.tsx
Normal file
26
packages/ui/src/stories/ThemeToggle.stories.tsx
Normal file
|
|
@ -0,0 +1,26 @@
|
|||
import type { Meta, StoryObj } from "@storybook/react-vite";
|
||||
import { ThemeToggle } from "../components/ThemeToggle";
|
||||
|
||||
const meta = {
|
||||
title: "UI/ThemeToggle",
|
||||
component: ThemeToggle,
|
||||
args: {
|
||||
onThemeChange: () => undefined,
|
||||
theme: "dark",
|
||||
},
|
||||
} satisfies Meta<typeof ThemeToggle>;
|
||||
|
||||
export default meta;
|
||||
|
||||
type Story = StoryObj<typeof meta>;
|
||||
|
||||
export const Dark: Story = {};
|
||||
|
||||
export const Light: Story = {
|
||||
args: {
|
||||
theme: "light",
|
||||
},
|
||||
globals: {
|
||||
theme: "light",
|
||||
},
|
||||
};
|
||||
16
packages/ui/src/stories/WeatherModule.stories.tsx
Normal file
16
packages/ui/src/stories/WeatherModule.stories.tsx
Normal file
|
|
@ -0,0 +1,16 @@
|
|||
import type { Meta, StoryObj } from "@storybook/react-vite";
|
||||
import { WeatherModule } from "../components/WeatherModule";
|
||||
import { moduleBlocks } from "./story-data";
|
||||
|
||||
const meta = {
|
||||
title: "UI/WeatherModule",
|
||||
component: WeatherModule,
|
||||
args: {
|
||||
module: moduleBlocks.compact,
|
||||
},
|
||||
} satisfies Meta<typeof WeatherModule>;
|
||||
|
||||
export default meta;
|
||||
type Story = StoryObj<typeof meta>;
|
||||
|
||||
export const Default: Story = {};
|
||||
258
packages/ui/src/stories/story-data.ts
Normal file
258
packages/ui/src/stories/story-data.ts
Normal file
|
|
@ -0,0 +1,258 @@
|
|||
import { dashboardPreviewFixtures } from "../fixtures";
|
||||
import type {
|
||||
UiDashboardPreview,
|
||||
UiModuleBlock,
|
||||
UiServiceGroup,
|
||||
UiServiceRow,
|
||||
UiSeverity,
|
||||
UiStatusItem,
|
||||
UiTelemetryCard,
|
||||
} from "../types";
|
||||
|
||||
export const primaryDashboard = dashboardPreviewFixtures.primary;
|
||||
export const secondaryDashboard = dashboardPreviewFixtures.secondary;
|
||||
|
||||
export const emptyDashboard: UiDashboardPreview = {
|
||||
eyebrow: "Preview Surface",
|
||||
title: "Empty Console",
|
||||
subtitle: "No records available",
|
||||
telemetry: [],
|
||||
modules: [],
|
||||
serviceGroups: [],
|
||||
statusItems: [],
|
||||
};
|
||||
|
||||
export const moduleBlocks: Record<string, UiModuleBlock> = {
|
||||
compact: {
|
||||
id: "module-compact",
|
||||
title: "Local Node",
|
||||
value: "21.4 C",
|
||||
detail: "static sample",
|
||||
icon: "mdi:weather-partly-cloudy",
|
||||
severity: "ok",
|
||||
},
|
||||
unavailable: {
|
||||
id: "module-unavailable",
|
||||
title: "External Signal",
|
||||
value: "n/a",
|
||||
detail: "fallback value",
|
||||
icon: "mdi:cloud-off-outline",
|
||||
severity: "unavailable",
|
||||
},
|
||||
long: {
|
||||
id: "module-long",
|
||||
title: "Regional Aggregate Signal",
|
||||
value: "manual review queued",
|
||||
detail: "long generic label wraps without layout shift",
|
||||
icon: "mdi:map-marker-radius-outline",
|
||||
severity: "warning",
|
||||
},
|
||||
};
|
||||
|
||||
export const telemetryCards: Record<string, UiTelemetryCard> = {
|
||||
percent: {
|
||||
id: "telemetry-percent",
|
||||
label: "Capacity Used",
|
||||
value: { kind: "percent", value: 82 },
|
||||
progress: 82,
|
||||
icon: "mdi:gauge",
|
||||
severity: "ok",
|
||||
detail: "static sample",
|
||||
sparkline: [24, 36, 28, 44, 52, 82],
|
||||
},
|
||||
bytes: {
|
||||
id: "telemetry-bytes",
|
||||
label: "Data Volume",
|
||||
value: { kind: "bytes", value: 982451653, precision: 1 },
|
||||
icon: "mdi:database",
|
||||
severity: "neutral",
|
||||
detail: "static sample",
|
||||
sparkline: [8, 12, 20, 18, 24, 29],
|
||||
},
|
||||
temperature: {
|
||||
id: "telemetry-temperature",
|
||||
label: "Node Temperature",
|
||||
value: { kind: "temperature", value: 21.4, precision: 1 },
|
||||
icon: "mdi:thermometer",
|
||||
severity: "neutral",
|
||||
detail: "static sample",
|
||||
sparkline: [18, 20, 19, 21, 20, 21.4],
|
||||
},
|
||||
latency: {
|
||||
id: "telemetry-latency",
|
||||
label: "Median Latency",
|
||||
value: { kind: "latency", value: 87 },
|
||||
icon: "mdi:timer-outline",
|
||||
severity: "warning",
|
||||
detail: "static sample",
|
||||
sparkline: [45, 51, 72, 63, 80, 87],
|
||||
},
|
||||
unavailable: {
|
||||
id: "telemetry-unavailable",
|
||||
label: "Remote Signal",
|
||||
value: { kind: "text", value: "n/a" },
|
||||
icon: "mdi:cloud-off-outline",
|
||||
severity: "unavailable",
|
||||
detail: "fallback value",
|
||||
},
|
||||
stale: {
|
||||
id: "telemetry-stale",
|
||||
label: "Sync Age",
|
||||
value: { kind: "text", value: "stale" },
|
||||
icon: "mdi:clock-alert-outline",
|
||||
severity: "stale",
|
||||
detail: "cached sample",
|
||||
sparkline: [22, 22, 22, 22, 22, 22],
|
||||
},
|
||||
danger: {
|
||||
id: "telemetry-danger",
|
||||
label: "Error Budget",
|
||||
value: { kind: "percent", value: 7 },
|
||||
progress: 7,
|
||||
icon: "mdi:alert-octagon-outline",
|
||||
severity: "danger",
|
||||
detail: "threshold breached",
|
||||
sparkline: [56, 41, 34, 20, 13, 7],
|
||||
},
|
||||
loading: {
|
||||
id: "telemetry-loading",
|
||||
label: "Pending Refresh",
|
||||
value: { kind: "text", value: "sync" },
|
||||
icon: "mdi:progress-clock",
|
||||
severity: "loading",
|
||||
detail: "waiting for update",
|
||||
},
|
||||
long: {
|
||||
id: "telemetry-long",
|
||||
label: "Very Long Generic Source Label That Must Wrap",
|
||||
value: { kind: "percent", value: 63 },
|
||||
progress: 63,
|
||||
icon: "mdi:chart-box-outline",
|
||||
severity: "neutral",
|
||||
detail: "long source label",
|
||||
sparkline: [14, 20, 28, 31, 49, 63],
|
||||
},
|
||||
};
|
||||
|
||||
export const serviceRows: Record<string, UiServiceRow> = {
|
||||
normal: row("service-normal", "Ingest", "Event intake pipeline", "mdi:arrow-collapse-down", "ok", "1.252 ms", {
|
||||
href: "#ingest",
|
||||
label: "Open ingest",
|
||||
}),
|
||||
down: row("service-down", "Replica", "Replica traffic cell", "mdi:access-point-off", "danger", "down"),
|
||||
degraded: row("service-degraded", "Scheduler", "Timed job coordinator", "mdi:calendar-clock", "warning", "1.487 ms"),
|
||||
stale: row("service-stale", "Archive", "Cold storage transfer", "mdi:archive-clock", "stale", "paused"),
|
||||
noLink: row("service-no-link", "Policy", "Rules evaluation", "mdi:shield-check", "neutral", "manual"),
|
||||
long: row(
|
||||
"service-long",
|
||||
"Long Generic Service Name That Wraps Cleanly",
|
||||
"Long generic service description with enough detail to exercise wrapping in constrained panels",
|
||||
"mdi:text-box-search-outline",
|
||||
"warning",
|
||||
"review queued",
|
||||
),
|
||||
};
|
||||
|
||||
export const serviceGroups: Record<string, UiServiceGroup> = {
|
||||
short: {
|
||||
id: "group-short",
|
||||
title: "Short List",
|
||||
services: [serviceRows.normal, serviceRows.degraded],
|
||||
},
|
||||
long: {
|
||||
id: "group-long",
|
||||
title: "Long List",
|
||||
services: [
|
||||
serviceRows.normal,
|
||||
serviceRows.degraded,
|
||||
serviceRows.stale,
|
||||
serviceRows.down,
|
||||
serviceRows.noLink,
|
||||
serviceRows.long,
|
||||
],
|
||||
},
|
||||
empty: {
|
||||
id: "group-empty",
|
||||
title: "Empty Group",
|
||||
services: [],
|
||||
},
|
||||
mixed: {
|
||||
id: "group-mixed",
|
||||
title: "Mixed Statuses",
|
||||
services: [serviceRows.normal, serviceRows.down, serviceRows.degraded, serviceRows.stale],
|
||||
summary: [
|
||||
{ id: "summary-ok", label: "Ok", value: "3", severity: "ok" },
|
||||
{ id: "summary-warn", label: "Warn", value: "1", severity: "warning" },
|
||||
{ id: "summary-down", label: "Down", value: "1", severity: "danger" },
|
||||
],
|
||||
},
|
||||
};
|
||||
|
||||
export const statusItems: Record<string, UiStatusItem> = {
|
||||
ok: { id: "status-ok", label: "System", value: "Operational", severity: "ok" },
|
||||
degraded: { id: "status-degraded", label: "Routing", value: "Degraded", severity: "warning" },
|
||||
incident: { id: "status-incident", label: "Incident", value: "Active", severity: "danger" },
|
||||
syncing: { id: "status-syncing", label: "Refresh", value: "Syncing", severity: "loading" },
|
||||
stale: { id: "status-stale", label: "Last Sync", value: "18 minutes ago", severity: "stale" },
|
||||
action: {
|
||||
id: "status-action",
|
||||
label: "Action",
|
||||
value: "Inspect",
|
||||
severity: "neutral",
|
||||
link: { href: "#inspect", label: "Inspect status" },
|
||||
},
|
||||
long: {
|
||||
id: "status-long",
|
||||
label: "Long Generic Status Label",
|
||||
value: "long generic status value wraps",
|
||||
severity: "neutral",
|
||||
},
|
||||
};
|
||||
|
||||
export const eightTelemetryCards = [
|
||||
telemetryCards.percent,
|
||||
telemetryCards.bytes,
|
||||
telemetryCards.temperature,
|
||||
telemetryCards.latency,
|
||||
telemetryCards.unavailable,
|
||||
telemetryCards.stale,
|
||||
telemetryCards.danger,
|
||||
telemetryCards.loading,
|
||||
];
|
||||
|
||||
export const sixteenTelemetryCards = Array.from({ length: 16 }, (_, index) => {
|
||||
const card = eightTelemetryCards[index % eightTelemetryCards.length];
|
||||
return {
|
||||
...card,
|
||||
id: `${card.id}-${index}`,
|
||||
label: `${card.label} ${index + 1}`,
|
||||
};
|
||||
});
|
||||
|
||||
export const mixedStatusStrip = [
|
||||
statusItems.ok,
|
||||
statusItems.degraded,
|
||||
statusItems.incident,
|
||||
statusItems.syncing,
|
||||
statusItems.stale,
|
||||
];
|
||||
|
||||
export const fullCompositionDashboard: UiDashboardPreview = {
|
||||
...primaryDashboard,
|
||||
telemetry: eightTelemetryCards,
|
||||
modules: [moduleBlocks.compact, moduleBlocks.unavailable],
|
||||
serviceGroups: [serviceGroups.mixed, serviceGroups.short, serviceGroups.long],
|
||||
statusItems: mixedStatusStrip,
|
||||
};
|
||||
|
||||
function row(
|
||||
id: string,
|
||||
label: string,
|
||||
description: string,
|
||||
icon: string,
|
||||
severity: UiSeverity,
|
||||
detail: string,
|
||||
link?: UiServiceRow["link"],
|
||||
): UiServiceRow {
|
||||
return { id, label, description, icon, severity, detail, link };
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue