feat(ui): establish shared design system foundations

This commit is contained in:
2026-09-08 07:09:05 +03:00
parent 36698322b7
commit d762ba5034
18 changed files with 401 additions and 40 deletions
+58
View File
@@ -0,0 +1,58 @@
import { Button, type ButtonProps } from "@mantine/core";
import type { Meta, StoryObj } from "@storybook/react-vite";
import { expect, fn, userEvent, within } from "storybook/test";
type ButtonStoryArgs = ButtonProps & { onClick: () => void };
const meta = {
title: "Design System/Components/Button",
component: Button,
tags: ["autodocs"],
args: {
children: "Выполнить пример",
onClick: fn(),
loading: false,
disabled: false,
variant: "filled",
},
argTypes: {
children: { control: "text" },
variant: { control: "select", options: ["filled", "default", "subtle"] },
loading: { control: "boolean" },
disabled: { control: "boolean" },
onClick: { control: false },
},
parameters: {
docs: {
description: {
component:
"Прямой Mantine Button с общей темой WealthLedger, без wrapper. Filled — основное действие; default — вторичное действие/retry; subtle — малозаметное вспомогательное действие. Radius md, primary blue и keyboard focus приходят из темы. Дайте кнопке доступное имя; loading означает mutation, disabled — недоступное действие. Loading/disabled не исполняют callback. Actions и interaction проверяют локальный callback, не API recovery.",
},
},
},
} satisfies Meta<ButtonStoryArgs>;
export default meta;
type Story = StoryObj<ButtonStoryArgs>;
export const Primary: Story = {
name: "Основное действие",
play: async ({ canvasElement, args }) => {
const button = within(canvasElement).getByRole("button", {
name: String(args.children),
});
button.focus();
await expect(button).toHaveFocus();
await userEvent.keyboard("{Enter}");
await expect(args.onClick).toHaveBeenCalled();
},
};
export const Secondary: Story = {
name: "Вторичное действие",
args: { variant: "default" },
};
export const Subtle: Story = {
name: "Вспомогательное действие",
args: { variant: "subtle" },
};
export const Loading: Story = { name: "Выполнение", args: { loading: true } };
export const Disabled: Story = { name: "Недоступно", args: { disabled: true } };