Add frameworks listing and import
Signed-off-by: Bryan Frimin <bryan@getprobo.com> Signed-off-by: Sacha Al Himdani <sacha@getprobo.com>
This commit is contained in:
committed by
Sacha Al Himdani
parent
7cb84d8ce8
commit
1870e050ce
@@ -1,23 +1,33 @@
|
||||
import clsx from "clsx";
|
||||
import { tv } from "tailwind-variants";
|
||||
|
||||
type Props = {
|
||||
name: string;
|
||||
src?: string | null;
|
||||
size?: "s" | "m" | "l" | "xl";
|
||||
className?: string;
|
||||
};
|
||||
|
||||
export function Avatar({ name, src, size = "m" }: Props) {
|
||||
const className = clsx(
|
||||
"bg-txt-success text-txt-invert rounded-full font-semibold flex items-center justify-center flex-none",
|
||||
size === "s" && "size-5 text-xss",
|
||||
size === "m" && "size-6 text-xxs",
|
||||
size === "l" && "size-8 text-sm",
|
||||
size === "xl" && "size-16 text-3xl",
|
||||
);
|
||||
if (src) {
|
||||
return <img className={className} src={src} alt={name} />;
|
||||
const avatar = tv({
|
||||
base: "bg-txt-success text-txt-invert rounded-full font-semibold flex items-center justify-center flex-none",
|
||||
variants: {
|
||||
size: {
|
||||
s: "size-5 text-xss",
|
||||
m: "size-6 text-xxs",
|
||||
l: "size-8 text-sm",
|
||||
xl: "size-16 text-3xl",
|
||||
},
|
||||
},
|
||||
defaultVariants: {
|
||||
size: "m",
|
||||
},
|
||||
});
|
||||
|
||||
export function Avatar(props: Props) {
|
||||
const className = avatar(props);
|
||||
if (props.src) {
|
||||
return <img className={className} src={props.src} alt={props.name} />;
|
||||
}
|
||||
return <div className={className}>{extractInitials(name ?? "")}</div>;
|
||||
return <div className={className}>{extractInitials(props.name ?? "")}</div>;
|
||||
}
|
||||
|
||||
function extractInitials(name: string) {
|
||||
|
||||
@@ -74,7 +74,7 @@ export function ActionDropdown(
|
||||
{...props}
|
||||
toggle={
|
||||
<Button
|
||||
className="inline-flex"
|
||||
className="inline-flex isolate z-5"
|
||||
variant={props.variant ?? "tertiary"}
|
||||
icon={IconDotGrid1x3Horizontal}
|
||||
/>
|
||||
|
||||
@@ -37,17 +37,22 @@ export const dialog = tv({
|
||||
},
|
||||
});
|
||||
|
||||
export type DialogRef = RefObject<{
|
||||
open: () => void;
|
||||
close: () => void;
|
||||
} | null>;
|
||||
|
||||
type Props = {
|
||||
trigger?: ReactNode;
|
||||
title?: ReactNode;
|
||||
children?: ReactNode;
|
||||
defaultOpen?: boolean;
|
||||
className?: string;
|
||||
ref?: RefObject<{ open: () => void; close: () => void } | null>;
|
||||
ref?: DialogRef;
|
||||
};
|
||||
|
||||
export const useDialogRef = () => {
|
||||
return useRef<{ open: () => void; close: () => void } | null>(null);
|
||||
export const useDialogRef = (): DialogRef => {
|
||||
return useRef(null);
|
||||
};
|
||||
|
||||
export function Dialog({
|
||||
|
||||
@@ -0,0 +1,12 @@
|
||||
import { FrameworkSelector } from "./FrameworkSelector";
|
||||
import type { Meta, StoryObj } from "@storybook/react";
|
||||
|
||||
export default {
|
||||
title: "Molecules/FrameworkSelector",
|
||||
component: FrameworkSelector,
|
||||
argTypes: {},
|
||||
} satisfies Meta<typeof FrameworkSelector>;
|
||||
|
||||
type Story = StoryObj<typeof FrameworkSelector>;
|
||||
|
||||
export const Default: Story = {};
|
||||
@@ -0,0 +1,76 @@
|
||||
import { Dropdown, DropdownItem } from "../../Atoms/Dropdown/Dropdown";
|
||||
import { IconChevronDown, IconPlusLarge } from "../../Atoms/Icons";
|
||||
import { Button } from "../../Atoms/Button/Button";
|
||||
import { availableFrameworks } from "@probo/helpers";
|
||||
import { useTranslate } from "@probo/i18n";
|
||||
|
||||
type Framework = (typeof availableFrameworks)[number];
|
||||
|
||||
type Props = {
|
||||
disabled?: boolean;
|
||||
onSelect: (frameworkId: string) => void;
|
||||
};
|
||||
|
||||
export function FrameworkSelector({ disabled, onSelect }: Props) {
|
||||
const { __ } = useTranslate();
|
||||
return (
|
||||
<Dropdown
|
||||
toggle={
|
||||
<Button
|
||||
icon={IconPlusLarge}
|
||||
iconAfter={IconChevronDown}
|
||||
disabled={disabled}
|
||||
>
|
||||
{__("New framework")}
|
||||
</Button>
|
||||
}
|
||||
>
|
||||
<FrameworkItem onClick={() => onSelect("custom")} />
|
||||
{availableFrameworks.map((framework) => (
|
||||
<FrameworkItem
|
||||
key={framework.id}
|
||||
framework={framework}
|
||||
onClick={() => onSelect(framework.id)}
|
||||
/>
|
||||
))}
|
||||
</Dropdown>
|
||||
);
|
||||
}
|
||||
|
||||
function FrameworkItem(props: { framework?: Framework; onClick: () => void }) {
|
||||
const { __ } = useTranslate();
|
||||
if (!props.framework) {
|
||||
return (
|
||||
<DropdownItem onClick={props.onClick} className="">
|
||||
<div className="rounded-full size-8 bg-highlight text-txt-primary flex items-center justify-center">
|
||||
<IconPlusLarge size={16} />
|
||||
</div>
|
||||
<div className="space-y-[2px]">
|
||||
<div className="text-sm font-medium">
|
||||
{__("Custom framework")}
|
||||
</div>
|
||||
<div className="text-xs text-txt-secondary">
|
||||
{__("Start from scratch")}
|
||||
</div>
|
||||
</div>
|
||||
</DropdownItem>
|
||||
);
|
||||
}
|
||||
return (
|
||||
<DropdownItem onClick={props.onClick} className="">
|
||||
<img
|
||||
src={props.framework.logo}
|
||||
alt={props.framework.name}
|
||||
className="size-8"
|
||||
/>
|
||||
<div className="space-y-[2px]">
|
||||
<div className="text-sm font-medium">
|
||||
{props.framework.name}
|
||||
</div>
|
||||
<div className="text-xs text-txt-secondary">
|
||||
{props.framework.description}
|
||||
</div>
|
||||
</div>
|
||||
</DropdownItem>
|
||||
);
|
||||
}
|
||||
@@ -47,6 +47,7 @@ export {
|
||||
DialogFooter,
|
||||
DialogTitle,
|
||||
useDialogRef,
|
||||
type DialogRef,
|
||||
} from "./Molecules/Dialog/Dialog";
|
||||
export { useConfirm } from "./Molecules/Dialog/ConfirmDialog";
|
||||
export { RiskBadge } from "./Molecules/Badge/RiskBadge";
|
||||
@@ -58,6 +59,7 @@ export { Combobox, ComboboxItem } from "./Molecules/Combobox/Combobox";
|
||||
export { FileButton } from "./Molecules/FileButton/FileButton";
|
||||
export { MeasureBadge } from "./Molecules/Badge/MeasureBadge";
|
||||
export { MeasureImplementation } from "./Molecules/MeasureImplementation/MeasureImplementation";
|
||||
export { FrameworkSelector } from "./Molecules/FrameworkSelector/FrameworkSelector";
|
||||
|
||||
// Hooks
|
||||
export { useToast, Toasts } from "./Atoms/Toasts/Toasts";
|
||||
|
||||
Reference in New Issue
Block a user