117 lines
2.8 KiB
TypeScript
117 lines
2.8 KiB
TypeScript
import type { FormHTMLAttributes, HTMLAttributes, ReactNode } from "react";
|
|
|
|
export type ContentGridColumns = 1 | 2 | 3 | 4;
|
|
export type ContentGridGap = "compact" | "small" | "default" | "loose";
|
|
export type ContentGridSpacing = "none" | "block";
|
|
export type ContentGridCollapseAt = "narrow" | "workspace" | "standard" | "wide" | "never";
|
|
|
|
export type ContentGridProps = HTMLAttributes<HTMLDivElement> & {
|
|
children: ReactNode;
|
|
columns?: ContentGridColumns;
|
|
gap?: ContentGridGap;
|
|
spacing?: ContentGridSpacing;
|
|
collapseAt?: ContentGridCollapseAt;
|
|
align?: "start" | "stretch";
|
|
};
|
|
|
|
export default function ContentGrid({
|
|
children,
|
|
columns = 2,
|
|
gap = "default",
|
|
spacing = "none",
|
|
collapseAt = "workspace",
|
|
align = "start",
|
|
className = "",
|
|
...props
|
|
}: ContentGridProps) {
|
|
return (
|
|
<div
|
|
{...props}
|
|
className={[
|
|
"content-grid-layout",
|
|
`content-grid-columns-${columns}`,
|
|
`content-grid-gap-${gap}`,
|
|
`content-grid-spacing-${spacing}`,
|
|
`content-grid-collapse-${collapseAt}`,
|
|
`content-grid-align-${align}`,
|
|
className
|
|
].filter(Boolean).join(" ")}
|
|
>
|
|
{children}
|
|
</div>
|
|
);
|
|
}
|
|
|
|
export type FormGridProps = Omit<ContentGridProps, "align">;
|
|
|
|
export function FormGrid({
|
|
children,
|
|
columns = 1,
|
|
gap = "default",
|
|
collapseAt = "standard",
|
|
className = "",
|
|
...props
|
|
}: FormGridProps) {
|
|
return (
|
|
<ContentGrid
|
|
{...props}
|
|
columns={columns}
|
|
gap={gap}
|
|
collapseAt={collapseAt}
|
|
align="start"
|
|
className={["form-grid-layout", className].filter(Boolean).join(" ")}
|
|
>
|
|
{children}
|
|
</ContentGrid>
|
|
);
|
|
}
|
|
|
|
export type FormLayoutProps = FormHTMLAttributes<HTMLFormElement> & {
|
|
children: ReactNode;
|
|
columns?: ContentGridColumns;
|
|
gap?: ContentGridGap;
|
|
spacing?: ContentGridSpacing;
|
|
collapseAt?: ContentGridCollapseAt;
|
|
};
|
|
|
|
export function FormLayout({
|
|
children,
|
|
columns = 1,
|
|
gap = "default",
|
|
spacing = "none",
|
|
collapseAt = "standard",
|
|
className = "",
|
|
...props
|
|
}: FormLayoutProps) {
|
|
return (
|
|
<form
|
|
{...props}
|
|
className={[
|
|
"content-grid-layout",
|
|
"form-grid-layout",
|
|
`content-grid-columns-${columns}`,
|
|
`content-grid-gap-${gap}`,
|
|
`content-grid-spacing-${spacing}`,
|
|
`content-grid-collapse-${collapseAt}`,
|
|
"content-grid-align-start",
|
|
className
|
|
].filter(Boolean).join(" ")}
|
|
>
|
|
{children}
|
|
</form>
|
|
);
|
|
}
|
|
|
|
export type GridItemProps = HTMLAttributes<HTMLDivElement> & {
|
|
children: ReactNode;
|
|
span?: "one" | "two" | "full";
|
|
};
|
|
|
|
export function GridItem({ children, span = "one", className = "", ...props }: GridItemProps) {
|
|
return (
|
|
<div {...props} className={["content-grid-item", `content-grid-item-${span}`, className].filter(Boolean).join(" ")}>
|
|
{children}
|
|
</div>
|
|
);
|
|
}
|