Add shared WebUI layout primitives
This commit is contained in:
@@ -0,0 +1,109 @@
|
||||
import type { FormHTMLAttributes, HTMLAttributes, ReactNode } from "react";
|
||||
|
||||
export type ContentGridColumns = 1 | 2 | 3 | 4;
|
||||
export type ContentGridGap = "compact" | "small" | "default" | "loose";
|
||||
export type ContentGridCollapseAt = "narrow" | "workspace" | "standard" | "wide" | "never";
|
||||
|
||||
export type ContentGridProps = HTMLAttributes<HTMLDivElement> & {
|
||||
children: ReactNode;
|
||||
columns?: ContentGridColumns;
|
||||
gap?: ContentGridGap;
|
||||
collapseAt?: ContentGridCollapseAt;
|
||||
align?: "start" | "stretch";
|
||||
};
|
||||
|
||||
export default function ContentGrid({
|
||||
children,
|
||||
columns = 2,
|
||||
gap = "default",
|
||||
collapseAt = "workspace",
|
||||
align = "start",
|
||||
className = "",
|
||||
...props
|
||||
}: ContentGridProps) {
|
||||
return (
|
||||
<div
|
||||
{...props}
|
||||
className={[
|
||||
"content-grid-layout",
|
||||
`content-grid-columns-${columns}`,
|
||||
`content-grid-gap-${gap}`,
|
||||
`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;
|
||||
collapseAt?: ContentGridCollapseAt;
|
||||
};
|
||||
|
||||
export function FormLayout({
|
||||
children,
|
||||
columns = 1,
|
||||
gap = "default",
|
||||
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-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>
|
||||
);
|
||||
}
|
||||
Reference in New Issue
Block a user