Shadcn autocomponents
The Shadcn autocomponents are a set of components that are made using the Shadcn design system and are designed to be used in web apps. These components have the base autocomponent props and the Shadcn design system component overrides.
For more information on the autocomponents, see the @gadgetinc/react/auto references.
Usage
Within a Gadget app made with the web template, import Shadcn autocomponents from the web/components/auto.ts
file:
import { AutoForm, AutoTable, AutoInput, AutoSubmit } from "../components/auto";
import { AutoForm, AutoTable, AutoInput, AutoSubmit } from "../components/auto";
For example, to use the AutoForm
component:
1import { AutoForm, AutoInput, AutoSubmit } from "../components/auto";2import { api } from "../api";34export default function () {5 return (6 <AutoForm action={api.widget.create}>7 <AutoInput field="name" />8 <AutoSubmit />9 </AutoForm>10 );11}
1import { AutoForm, AutoInput, AutoSubmit } from "../components/auto";2import { api } from "../api";34export default function () {5 return (6 <AutoForm action={api.widget.create}>7 <AutoInput field="name" />8 <AutoSubmit />9 </AutoForm>10 );11}
Customization
You can fully customize the base components used to create the Shadcn autocomponents. In the web/components/ui/
folder, there is a collection of component files that are used to create the autocomponents, and these can be easily modified to change the look of the autocomponents.
For example, the default Button
component has variants with different styles, and to to change those styles, the original web/components/ui/button.tsx
file can be modified.
1import * as React from "react";2import { Slot } from "@radix-ui/react-slot";3import { cva, type VariantProps } from "class-variance-authority";45import { cn } from "@/lib/utils";67const buttonVariants = cva(8 "inline-flex items-center justify-center gap-2 whitespace-nowrap rounded-md text-sm font-medium transition-colors focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-ring disabled:pointer-events-none disabled:opacity-50 [&_svg]:pointer-events-none [&_svg]:size-4 [&_svg]:shrink-0 shadow",9 {10 variants: {11 variant: {12 // Colors have been changed to black and white13 primary: "bg-black text-white hover:bg-black/90",14 secondary: "bg-gray-200 text-black hover:bg-gray-300",15 },16 size: {17 default: "h-9 px-4 py-2",18 sm: "h-8 rounded-md px-3 text-xs",19 lg: "h-10 rounded-md px-8",20 icon: "h-9 w-9",21 },22 },23 defaultVariants: {24 variant: "primary",25 size: "default",26 },27 }28);2930export interface ButtonProps extends React.ButtonHTMLAttributes<HTMLButtonElement>, VariantProps<typeof buttonVariants> {31 asChild?: boolean;32}3334const Button = React.forwardRef<HTMLButtonElement, ButtonProps>(({ className, variant, size, asChild = false, ...props }, ref) => {35 const Comp = asChild ? Slot : "button";36 return <Comp className={cn(buttonVariants({ variant, size, className }))} ref={ref} {...props} />;37});38Button.displayName = "Button";3940export { Button, buttonVariants };
1import * as React from "react";2import { Slot } from "@radix-ui/react-slot";3import { cva, type VariantProps } from "class-variance-authority";45import { cn } from "@/lib/utils";67const buttonVariants = cva(8 "inline-flex items-center justify-center gap-2 whitespace-nowrap rounded-md text-sm font-medium transition-colors focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-ring disabled:pointer-events-none disabled:opacity-50 [&_svg]:pointer-events-none [&_svg]:size-4 [&_svg]:shrink-0 shadow",9 {10 variants: {11 variant: {12 // Colors have been changed to black and white13 primary: "bg-black text-white hover:bg-black/90",14 secondary: "bg-gray-200 text-black hover:bg-gray-300",15 },16 size: {17 default: "h-9 px-4 py-2",18 sm: "h-8 rounded-md px-3 text-xs",19 lg: "h-10 rounded-md px-8",20 icon: "h-9 w-9",21 },22 },23 defaultVariants: {24 variant: "primary",25 size: "default",26 },27 }28);2930export interface ButtonProps extends React.ButtonHTMLAttributes<HTMLButtonElement>, VariantProps<typeof buttonVariants> {31 asChild?: boolean;32}3334const Button = React.forwardRef<HTMLButtonElement, ButtonProps>(({ className, variant, size, asChild = false, ...props }, ref) => {35 const Comp = asChild ? Slot : "button";36 return <Comp className={cn(buttonVariants({ variant, size, className }))} ref={ref} {...props} />;37});38Button.displayName = "Button";3940export { Button, buttonVariants };
Now, all buttons used in autocomponents will be made with the customized component. Now when using an autocomponent that uses a button such as <AutoSubmit />
, the button will now look like this:
1import { AutoForm, AutoButton } from "../components/auto";2import { api } from "../api";34export default function () {5 return (6 <AutoForm action={api.widget.create}>7 <AutoInput field="name" />8 <AutoSubmit>Primary</AutoSubmit>9 </AutoForm>10 );11}
1import { AutoForm, AutoButton } from "../components/auto";2import { api } from "../api";34export default function () {5 return (6 <AutoForm action={api.widget.create}>7 <AutoInput field="name" />8 <AutoSubmit>Primary</AutoSubmit>9 </AutoForm>10 );11}