Add risk forms

Signed-off-by: Bryan Frimin <bryan@getprobo.com>
Signed-off-by: Sacha Al Himdani <sacha@getprobo.com>
This commit is contained in:
Jonathan
2025-05-22 12:40:12 +02:00
committed by Sacha Al Himdani
parent 3d4ecf5f8f
commit fc45d2f00d
41 changed files with 2426 additions and 136 deletions

View File

@@ -0,0 +1,31 @@
import { Badge } from "./Badge";
import type { Meta, StoryObj } from "@storybook/react";
export default {
title: "Atoms/Badge",
component: Badge,
argTypes: {},
} satisfies Meta<typeof Badge>;
type Story = StoryObj<typeof Badge>;
export const Default: Story = {
render: () => (
<>
{(
[
"success",
"warning",
"danger",
"info",
"neutral",
"outline",
] as const
).map((variant) => (
<Badge key={variant} variant={variant}>
{variant}
</Badge>
))}
</>
),
};

View File

@@ -0,0 +1,24 @@
import type { HTMLAttributes } from "react";
import { tv } from "tailwind-variants";
type Props = {
variant?: "success" | "warning" | "danger" | "info" | "neutral" | "outline";
} & HTMLAttributes<HTMLDivElement>;
const badge = tv({
base: "text-xs font-medium py-[2px] px-[6px] rounded-lg w-max",
variants: {
variant: {
success: "bg-success text-txt-success",
warning: "bg-warning text-txt-warning",
danger: "bg-danger text-txt-danger",
info: "bg-info text-txt-info",
neutral: "bg-subtle text-txt-secondary",
outline: "text-txt-tertiary border border-border-low",
},
},
});
export function Badge(props: Props) {
return <div className={badge(props)} {...props} />;
}

View File

@@ -1,8 +1,10 @@
import type { FC, PropsWithChildren, ReactNode } from "react";
import type { ComponentProps, FC, PropsWithChildren, ReactNode } from "react";
import * as DropdownMenu from "@radix-ui/react-dropdown-menu";
import { clsx } from "clsx";
import type { IconProps } from "../Icons/type.ts";
import { tv } from "tailwind-variants";
import { IconDotGrid1x3Horizontal } from "../Icons/IconDotGrid1x3Horizontal.tsx";
import { Button } from "../Button/Button.tsx";
type Props = PropsWithChildren<{
toggle: ReactNode;
@@ -38,7 +40,8 @@ type DropdownItemProps = PropsWithChildren<{
icon?: FC<IconProps>;
asChild?: boolean;
variant?: "primary" | "tertiary" | "danger";
}>;
}> &
ComponentProps<typeof DropdownMenu.Item>;
const dropdownItem = tv({
base: "text-txt-primary flex items-center gap-2 hover:bg-tertiary-hover active:bg-tertiary-pressed cursor-pointer p-2",
@@ -54,15 +57,28 @@ const dropdownItem = tv({
},
});
export function ActionDropdown(props: Omit<Props, "toggle">) {
return (
<Dropdown
{...props}
toggle={
<Button variant="tertiary" icon={IconDotGrid1x3Horizontal} />
}
/>
);
}
export function DropdownItem({
icon: IconComponent,
variant,
className,
children,
asChild,
...props
}: DropdownItemProps) {
return (
<DropdownMenu.Item
{...props}
className={clsx(dropdownItem({ variant }), className)}
asChild={asChild}
>

View File

@@ -85,6 +85,9 @@ const findSelectedOption = (
children: unknown[],
condition: (c: { props: Record<string, unknown> }) => boolean,
): ReactNode => {
if (children.length === 1) {
debugger;
}
const selectedOptions = children.find(
// @ts-expect-error We know that the children are ReactElements with props
(c) => isValidElement(c) && condition(c),
@@ -109,7 +112,7 @@ export function Select({
(c) => c.props.value?.toString() === value?.toString(),
)
: undefined;
console.log(childrenArr, valueNode);
return (
<Root onValueChange={onValueChange} value={value}>
<Trigger className={trigger({ ...props })} {...props}>

View File

@@ -0,0 +1,12 @@
import { Table } from "./Table";
import type { Meta, StoryObj } from "@storybook/react";
export default {
title: "Atoms/Table",
component: Table,
argTypes: {},
} satisfies Meta<typeof Table>;
type Story = StoryObj<typeof Table>;
export const Default: Story = {};

View File

@@ -0,0 +1,64 @@
import { createContext, useContext, type PropsWithChildren } from "react";
import { Card } from "../Card/Card";
import { Link } from "react-router";
import clsx from "clsx";
export function Table({ children }: PropsWithChildren) {
return (
<Card className="relative w-full overflow-auto">
<table className="w-full text-left">{children}</table>
</Card>
);
}
export function Thead({ children }: PropsWithChildren) {
return (
<thead className="text-xs text-txt-tertiary font-semibold">
{children}
</thead>
);
}
export function Th({ children }: PropsWithChildren) {
return <th className="first:pl-6 last:pr-6 py-3">{children}</th>;
}
const TrContext = createContext({} as { to?: string });
export function Tr({ children, to }: PropsWithChildren<{ to?: string }>) {
return (
<TrContext value={{ to }}>
<tr
className={clsx(
"border-border-low border",
to && "hover:bg-subtle",
)}
>
{children}
</tr>
</TrContext>
);
}
export function Tbody({ children }: PropsWithChildren) {
return (
<tbody className="text-sm text-txt-primary bg-tertiary">
{children}
</tbody>
);
}
export function Td({
children,
noLink,
}: PropsWithChildren<{ noLink?: boolean }>) {
const { to } = useContext(TrContext);
if (!to || noLink) {
return <td className="first:pl-6 last:pr-6 py-3">{children}</td>;
}
return (
<td className="first:*:pl-6 *:block last:*:pr-6 py-3">
<Link to={to}>{children}</Link>
</td>
);
}