Compare commits

..

1 Commits

Author SHA1 Message Date
ShubhamPalriwala
b37b1dcb8f fix: onboarding example js for website surveys 2024-05-14 16:07:40 +05:30
647 changed files with 5374 additions and 7811 deletions

View File

@@ -1,6 +1,6 @@
import { Sidebar } from "./Sidebar";
import Sidebar from "./Sidebar";
export const LayoutApp = ({ children }: { children: React.ReactNode }) => {
export default function LayoutApp({ children }: { children: React.ReactNode }) {
return (
<div className="min-h-full">
{/* Static sidebar for desktop */}
@@ -10,4 +10,4 @@ export const LayoutApp = ({ children }: { children: React.ReactNode }) => {
<div className="flex flex-1 flex-col lg:pl-64">{children}</div>
</div>
);
};
}

View File

@@ -26,7 +26,7 @@ const secondaryNavigation = [
{ name: "Privacy", href: "#", icon: ShieldCheckIcon },
];
export const Sidebar = () => {
export default function Sidebar({}) {
return (
<div className="flex flex-grow flex-col overflow-y-auto bg-cyan-700 pb-4 pt-5">
<nav
@@ -63,4 +63,4 @@ export const Sidebar = () => {
</nav>
</div>
);
};
}

View File

@@ -1,31 +0,0 @@
import { type VariantProps, cva } from "class-variance-authority";
import * as React from "react";
import { classNames } from "../../lib/utils";
const badgeVariants = cva(
"inline-flex items-center rounded-full border px-2.5 py-0.5 text-xs font-semibold transition-colors focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2",
{
variants: {
variant: {
default: "border-transparent bg-primary text-primary-foreground hover:bg-primary/80",
secondary: "border-transparent bg-secondary text-secondary-foreground hover:bg-secondary/80",
destructive: "border-transparent bg-destructive text-destructive-foreground hover:bg-destructive/80",
outline: "text-foreground",
},
},
defaultVariants: {
variant: "default",
},
}
);
export interface BadgeProps
extends React.HTMLAttributes<HTMLDivElement>,
VariantProps<typeof badgeVariants> {}
function Badge({ className, variant, ...props }: BadgeProps) {
return <div className={classNames(badgeVariants({ variant }), className)} {...props} />;
}
export { Badge, badgeVariants };

View File

@@ -1,91 +0,0 @@
import { Slot } from "@radix-ui/react-slot";
import { ChevronRight, MoreHorizontal } from "lucide-react";
import * as React from "react";
import { classNames } from "../../lib/utils";
const Breadcrumb = React.forwardRef<
HTMLElement,
React.ComponentPropsWithoutRef<"nav"> & {
separator?: React.ReactNode;
}
>(({ ...props }, ref) => <nav ref={ref} aria-label="breadcrumb" {...props} />);
Breadcrumb.displayName = "Breadcrumb";
const BreadcrumbList = React.forwardRef<HTMLOListElement, React.ComponentPropsWithoutRef<"ol">>(
({ className, ...props }, ref) => (
<ol
ref={ref}
className={classNames(
"text-muted-foreground flex flex-wrap items-center gap-1.5 break-words text-sm sm:gap-2.5",
className
)}
{...props}
/>
)
);
BreadcrumbList.displayName = "BreadcrumbList";
const BreadcrumbItem = React.forwardRef<HTMLLIElement, React.ComponentPropsWithoutRef<"li">>(
({ className, ...props }, ref) => (
<li ref={ref} className={classNames("inline-flex items-center gap-1.5", className)} {...props} />
)
);
BreadcrumbItem.displayName = "BreadcrumbItem";
const BreadcrumbLink = React.forwardRef<
HTMLAnchorElement,
React.ComponentPropsWithoutRef<"a"> & {
asChild?: boolean;
}
>(({ asChild, className, ...props }, ref) => {
const Comp = asChild ? Slot : "a";
return (
<Comp ref={ref} className={classNames("hover:text-foreground transition-colors", className)} {...props} />
);
});
BreadcrumbLink.displayName = "BreadcrumbLink";
const BreadcrumbPage = React.forwardRef<HTMLSpanElement, React.ComponentPropsWithoutRef<"span">>(
({ className, ...props }, ref) => (
<span
ref={ref}
role="link"
aria-disabled="true"
aria-current="page"
className={classNames("text-foreground font-normal", className)}
{...props}
/>
)
);
BreadcrumbPage.displayName = "BreadcrumbPage";
const BreadcrumbSeparator = ({ children, className, ...props }: React.ComponentProps<"li">) => (
<li role="presentation" aria-hidden="true" className={classNames("[&>svg]:size-3.5", className)} {...props}>
{children ?? <ChevronRight />}
</li>
);
BreadcrumbSeparator.displayName = "BreadcrumbSeparator";
const BreadcrumbEllipsis = ({ className, ...props }: React.ComponentProps<"span">) => (
<span
role="presentation"
aria-hidden="true"
className={classNames("flex h-9 w-9 items-center justify-center", className)}
{...props}>
<MoreHorizontal className="h-4 w-4" />
<span className="sr-only">More</span>
</span>
);
BreadcrumbEllipsis.displayName = "BreadcrumbElipssis";
export {
Breadcrumb,
BreadcrumbEllipsis,
BreadcrumbItem,
BreadcrumbLink,
BreadcrumbList,
BreadcrumbPage,
BreadcrumbSeparator,
};

View File

@@ -1,47 +0,0 @@
import { Slot } from "@radix-ui/react-slot";
import { type VariantProps, cva } from "class-variance-authority";
import * as React from "react";
import { classNames } from "../../lib/utils";
const buttonVariants = cva(
"inline-flex items-center justify-center whitespace-nowrap rounded-md text-sm font-medium ring-offset-background transition-colors focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 disabled:pointer-events-none disabled:opacity-50",
{
variants: {
variant: {
default: "bg-primary text-primary-foreground hover:bg-primary/90",
destructive: "bg-destructive text-destructive-foreground hover:bg-destructive/90",
outline: "border border-input bg-background hover:bg-accent hover:text-accent-foreground",
secondary: "bg-secondary text-secondary-foreground hover:bg-secondary/80",
ghost: "hover:bg-accent hover:text-accent-foreground",
link: "text-primary underline-offset-4 hover:underline",
},
size: {
default: "h-10 px-4 py-2",
sm: "h-9 rounded-md px-3",
lg: "h-11 rounded-md px-8",
icon: "h-10 w-10",
},
},
defaultVariants: {
variant: "default",
size: "default",
},
}
);
export interface ButtonProps
extends React.ButtonHTMLAttributes<HTMLButtonElement>,
VariantProps<typeof buttonVariants> {
asChild?: boolean;
}
const Button = React.forwardRef<HTMLButtonElement, ButtonProps>(
({ className, variant, size, asChild = false, ...props }, ref) => {
const Comp = asChild ? Slot : "button";
return <Comp className={classNames(buttonVariants({ variant, size, className }))} ref={ref} {...props} />;
}
);
Button.displayName = "Button";
export { Button, buttonVariants };

View File

@@ -1,53 +0,0 @@
import * as React from "react";
import { classNames } from "../../lib/utils";
const Card = React.forwardRef<HTMLDivElement, React.HTMLAttributes<HTMLDivElement>>(
({ className, ...props }, ref) => (
<div
ref={ref}
className={classNames("bg-card text-card-foreground rounded-lg border shadow-sm", className)}
{...props}
/>
)
);
Card.displayName = "Card";
const CardHeader = React.forwardRef<HTMLDivElement, React.HTMLAttributes<HTMLDivElement>>(
({ className, ...props }, ref) => (
<div ref={ref} className={classNames("flex flex-col space-y-1.5 p-6", className)} {...props} />
)
);
CardHeader.displayName = "CardHeader";
const CardTitle = React.forwardRef<HTMLParagraphElement, React.HTMLAttributes<HTMLHeadingElement>>(
({ className, ...props }, ref) => (
<h3
ref={ref}
className={classNames("text-2xl font-semibold leading-none tracking-tight", className)}
{...props}
/>
)
);
CardTitle.displayName = "CardTitle";
const CardDescription = React.forwardRef<HTMLParagraphElement, React.HTMLAttributes<HTMLParagraphElement>>(
({ className, ...props }, ref) => (
<p ref={ref} className={classNames("text-muted-foreground text-sm", className)} {...props} />
)
);
CardDescription.displayName = "CardDescription";
const CardContent = React.forwardRef<HTMLDivElement, React.HTMLAttributes<HTMLDivElement>>(
({ className, ...props }, ref) => <div ref={ref} className={classNames("p-6 pt-0", className)} {...props} />
);
CardContent.displayName = "CardContent";
const CardFooter = React.forwardRef<HTMLDivElement, React.HTMLAttributes<HTMLDivElement>>(
({ className, ...props }, ref) => (
<div ref={ref} className={classNames("flex items-center p-6 pt-0", className)} {...props} />
)
);
CardFooter.displayName = "CardFooter";
export { Card, CardContent, CardDescription, CardFooter, CardHeader, CardTitle };

View File

@@ -1,182 +0,0 @@
"use client";
import * as DropdownMenuPrimitive from "@radix-ui/react-dropdown-menu";
import { Check, ChevronRight, Circle } from "lucide-react";
import * as React from "react";
import { classNames } from "../../lib/utils";
const DropdownMenu = DropdownMenuPrimitive.Root;
const DropdownMenuTrigger = DropdownMenuPrimitive.Trigger;
const DropdownMenuGroup = DropdownMenuPrimitive.Group;
const DropdownMenuPortal = DropdownMenuPrimitive.Portal;
const DropdownMenuSub = DropdownMenuPrimitive.Sub;
const DropdownMenuRadioGroup = DropdownMenuPrimitive.RadioGroup;
const DropdownMenuSubTrigger = React.forwardRef<
React.ElementRef<typeof DropdownMenuPrimitive.SubTrigger>,
React.ComponentPropsWithoutRef<typeof DropdownMenuPrimitive.SubTrigger> & {
inset?: boolean;
}
>(({ className, inset, children, ...props }, ref) => (
<DropdownMenuPrimitive.SubTrigger
ref={ref}
className={classNames(
"focus:bg-accent data-[state=open]:bg-accent flex cursor-default select-none items-center rounded-sm px-2 py-1.5 text-sm outline-none",
inset && "pl-8",
className
)}
{...props}>
{children}
<ChevronRight className="ml-auto h-4 w-4" />
</DropdownMenuPrimitive.SubTrigger>
));
DropdownMenuSubTrigger.displayName = DropdownMenuPrimitive.SubTrigger.displayName;
const DropdownMenuSubContent = React.forwardRef<
React.ElementRef<typeof DropdownMenuPrimitive.SubContent>,
React.ComponentPropsWithoutRef<typeof DropdownMenuPrimitive.SubContent>
>(({ className, ...props }, ref) => (
<DropdownMenuPrimitive.SubContent
ref={ref}
className={classNames(
"bg-popover text-popover-foreground data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2 z-50 min-w-[8rem] overflow-hidden rounded-md border p-1 shadow-lg",
className
)}
{...props}
/>
));
DropdownMenuSubContent.displayName = DropdownMenuPrimitive.SubContent.displayName;
const DropdownMenuContent = React.forwardRef<
React.ElementRef<typeof DropdownMenuPrimitive.Content>,
React.ComponentPropsWithoutRef<typeof DropdownMenuPrimitive.Content>
>(({ className, sideOffset = 4, ...props }, ref) => (
<DropdownMenuPrimitive.Portal>
<DropdownMenuPrimitive.Content
ref={ref}
sideOffset={sideOffset}
className={classNames(
"bg-popover text-popover-foreground data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2 z-50 min-w-[8rem] overflow-hidden rounded-md border p-1 shadow-md",
className
)}
{...props}
/>
</DropdownMenuPrimitive.Portal>
));
DropdownMenuContent.displayName = DropdownMenuPrimitive.Content.displayName;
const DropdownMenuItem = React.forwardRef<
React.ElementRef<typeof DropdownMenuPrimitive.Item>,
React.ComponentPropsWithoutRef<typeof DropdownMenuPrimitive.Item> & {
inset?: boolean;
}
>(({ className, inset, ...props }, ref) => (
<DropdownMenuPrimitive.Item
ref={ref}
className={classNames(
"focus:bg-accent focus:text-accent-foreground relative flex cursor-default select-none items-center rounded-sm px-2 py-1.5 text-sm outline-none transition-colors data-[disabled]:pointer-events-none data-[disabled]:opacity-50",
inset && "pl-8",
className
)}
{...props}
/>
));
DropdownMenuItem.displayName = DropdownMenuPrimitive.Item.displayName;
const DropdownMenuCheckboxItem = React.forwardRef<
React.ElementRef<typeof DropdownMenuPrimitive.CheckboxItem>,
React.ComponentPropsWithoutRef<typeof DropdownMenuPrimitive.CheckboxItem>
>(({ className, children, checked, ...props }, ref) => (
<DropdownMenuPrimitive.CheckboxItem
ref={ref}
className={classNames(
"focus:bg-accent focus:text-accent-foreground relative flex cursor-default select-none items-center rounded-sm py-1.5 pl-8 pr-2 text-sm outline-none transition-colors data-[disabled]:pointer-events-none data-[disabled]:opacity-50",
className
)}
checked={checked}
{...props}>
<span className="absolute left-2 flex h-3.5 w-3.5 items-center justify-center">
<DropdownMenuPrimitive.ItemIndicator>
<Check className="h-4 w-4" />
</DropdownMenuPrimitive.ItemIndicator>
</span>
{children}
</DropdownMenuPrimitive.CheckboxItem>
));
DropdownMenuCheckboxItem.displayName = DropdownMenuPrimitive.CheckboxItem.displayName;
const DropdownMenuRadioItem = React.forwardRef<
React.ElementRef<typeof DropdownMenuPrimitive.RadioItem>,
React.ComponentPropsWithoutRef<typeof DropdownMenuPrimitive.RadioItem>
>(({ className, children, ...props }, ref) => (
<DropdownMenuPrimitive.RadioItem
ref={ref}
className={classNames(
"focus:bg-accent focus:text-accent-foreground relative flex cursor-default select-none items-center rounded-sm py-1.5 pl-8 pr-2 text-sm outline-none transition-colors data-[disabled]:pointer-events-none data-[disabled]:opacity-50",
className
)}
{...props}>
<span className="absolute left-2 flex h-3.5 w-3.5 items-center justify-center">
<DropdownMenuPrimitive.ItemIndicator>
<Circle className="h-2 w-2 fill-current" />
</DropdownMenuPrimitive.ItemIndicator>
</span>
{children}
</DropdownMenuPrimitive.RadioItem>
));
DropdownMenuRadioItem.displayName = DropdownMenuPrimitive.RadioItem.displayName;
const DropdownMenuLabel = React.forwardRef<
React.ElementRef<typeof DropdownMenuPrimitive.Label>,
React.ComponentPropsWithoutRef<typeof DropdownMenuPrimitive.Label> & {
inset?: boolean;
}
>(({ className, inset, ...props }, ref) => (
<DropdownMenuPrimitive.Label
ref={ref}
className={classNames("px-2 py-1.5 text-sm font-semibold", inset && "pl-8", className)}
{...props}
/>
));
DropdownMenuLabel.displayName = DropdownMenuPrimitive.Label.displayName;
const DropdownMenuSeparator = React.forwardRef<
React.ElementRef<typeof DropdownMenuPrimitive.Separator>,
React.ComponentPropsWithoutRef<typeof DropdownMenuPrimitive.Separator>
>(({ className, ...props }, ref) => (
<DropdownMenuPrimitive.Separator
ref={ref}
className={classNames("bg-muted -mx-1 my-1 h-px", className)}
{...props}
/>
));
DropdownMenuSeparator.displayName = DropdownMenuPrimitive.Separator.displayName;
const DropdownMenuShortcut = ({ className, ...props }: React.HTMLAttributes<HTMLSpanElement>) => {
return <span className={classNames("ml-auto text-xs tracking-widest opacity-60", className)} {...props} />;
};
DropdownMenuShortcut.displayName = "DropdownMenuShortcut";
export {
DropdownMenu,
DropdownMenuCheckboxItem,
DropdownMenuContent,
DropdownMenuGroup,
DropdownMenuItem,
DropdownMenuLabel,
DropdownMenuPortal,
DropdownMenuRadioGroup,
DropdownMenuRadioItem,
DropdownMenuSeparator,
DropdownMenuShortcut,
DropdownMenuSub,
DropdownMenuSubContent,
DropdownMenuSubTrigger,
DropdownMenuTrigger,
};

View File

@@ -1,22 +0,0 @@
import * as React from "react";
import { classNames } from "../../lib/utils";
export interface InputProps extends React.InputHTMLAttributes<HTMLInputElement> {}
const Input = React.forwardRef<HTMLInputElement, InputProps>(({ className, type, ...props }, ref) => {
return (
<input
type={type}
className={classNames(
"border-input bg-background ring-offset-background placeholder:text-muted-foreground focus-visible:ring-ring flex h-10 w-full rounded-md border px-3 py-2 text-sm file:border-0 file:bg-transparent file:text-sm file:font-medium focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-offset-2 disabled:cursor-not-allowed disabled:opacity-50",
className
)}
ref={ref}
{...props}
/>
);
});
Input.displayName = "Input";
export { Input };

View File

@@ -1,89 +0,0 @@
import { ChevronLeft, ChevronRight, MoreHorizontal } from "lucide-react";
import * as React from "react";
import { classNames } from "../../lib/utils";
import { ButtonProps, buttonVariants } from "./button";
const Pagination = ({ className, ...props }: React.ComponentProps<"nav">) => (
<nav
role="navigation"
aria-label="pagination"
className={classNames("mx-auto flex w-full justify-center", className)}
{...props}
/>
);
Pagination.displayName = "Pagination";
const PaginationContent = React.forwardRef<HTMLUListElement, React.ComponentProps<"ul">>(
({ className, ...props }, ref) => (
<ul ref={ref} className={classNames("flex flex-row items-center gap-1", className)} {...props} />
)
);
PaginationContent.displayName = "PaginationContent";
const PaginationItem = React.forwardRef<HTMLLIElement, React.ComponentProps<"li">>(
({ className, ...props }, ref) => <li ref={ref} className={classNames("", className)} {...props} />
);
PaginationItem.displayName = "PaginationItem";
type PaginationLinkProps = {
isActive?: boolean;
} & Pick<ButtonProps, "size"> &
React.ComponentProps<"a">;
const PaginationLink = ({ className, isActive, size = "icon", ...props }: PaginationLinkProps) => (
<a
aria-current={isActive ? "page" : undefined}
className={classNames(
buttonVariants({
variant: isActive ? "outline" : "ghost",
size,
}),
className
)}
{...props}
/>
);
PaginationLink.displayName = "PaginationLink";
const PaginationPrevious = ({ className, ...props }: React.ComponentProps<typeof PaginationLink>) => (
<PaginationLink
aria-label="Go to previous page"
size="default"
className={classNames("gap-1 pl-2.5", className)}
{...props}>
<ChevronLeft className="h-4 w-4" />
<span>Previous</span>
</PaginationLink>
);
PaginationPrevious.displayName = "PaginationPrevious";
const PaginationNext = ({ className, ...props }: React.ComponentProps<typeof PaginationLink>) => (
<PaginationLink
aria-label="Go to next page"
size="default"
className={classNames("gap-1 pr-2.5", className)}
{...props}>
<span>Next</span>
<ChevronRight className="h-4 w-4" />
</PaginationLink>
);
PaginationNext.displayName = "PaginationNext";
const PaginationEllipsis = ({ className, ...props }: React.ComponentProps<"span">) => (
<span aria-hidden className={classNames("flex h-9 w-9 items-center justify-center", className)} {...props}>
<MoreHorizontal className="h-4 w-4" />
<span className="sr-only">More pages</span>
</span>
);
PaginationEllipsis.displayName = "PaginationEllipsis";
export {
Pagination,
PaginationContent,
PaginationEllipsis,
PaginationItem,
PaginationLink,
PaginationNext,
PaginationPrevious,
};

View File

@@ -1,24 +0,0 @@
"use client";
import * as ProgressPrimitive from "@radix-ui/react-progress";
import * as React from "react";
import { classNames } from "../../lib/utils";
const Progress = React.forwardRef<
React.ElementRef<typeof ProgressPrimitive.Root>,
React.ComponentPropsWithoutRef<typeof ProgressPrimitive.Root>
>(({ className, value, ...props }, ref) => (
<ProgressPrimitive.Root
ref={ref}
className={classNames("bg-secondary relative h-4 w-full overflow-hidden rounded-full", className)}
{...props}>
<ProgressPrimitive.Indicator
className="bg-primary h-full w-full flex-1 transition-all"
style={{ transform: `translateX(-${100 - (value || 0)}%)` }}
/>
</ProgressPrimitive.Root>
));
Progress.displayName = ProgressPrimitive.Root.displayName;
export { Progress };

View File

@@ -1,26 +0,0 @@
"use client";
import * as SeparatorPrimitive from "@radix-ui/react-separator";
import * as React from "react";
import { classNames } from "../../lib/utils";
const Separator = React.forwardRef<
React.ElementRef<typeof SeparatorPrimitive.Root>,
React.ComponentPropsWithoutRef<typeof SeparatorPrimitive.Root>
>(({ className, orientation = "horizontal", decorative = true, ...props }, ref) => (
<SeparatorPrimitive.Root
ref={ref}
decorative={decorative}
orientation={orientation}
className={classNames(
"bg-border shrink-0",
orientation === "horizontal" ? "h-[1px] w-full" : "h-full w-[1px]",
className
)}
{...props}
/>
));
Separator.displayName = SeparatorPrimitive.Root.displayName;
export { Separator };

View File

@@ -1,120 +0,0 @@
"use client";
import * as SheetPrimitive from "@radix-ui/react-dialog";
import { type VariantProps, cva } from "class-variance-authority";
import { X } from "lucide-react";
import * as React from "react";
import { classNames } from "../../lib/utils";
const Sheet = SheetPrimitive.Root;
const SheetTrigger = SheetPrimitive.Trigger;
const SheetClose = SheetPrimitive.Close;
const SheetPortal = SheetPrimitive.Portal;
const SheetOverlay = React.forwardRef<
React.ElementRef<typeof SheetPrimitive.Overlay>,
React.ComponentPropsWithoutRef<typeof SheetPrimitive.Overlay>
>(({ className, ...props }, ref) => (
<SheetPrimitive.Overlay
className={classNames(
"data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 fixed inset-0 z-50 bg-black/80",
className
)}
{...props}
ref={ref}
/>
));
SheetOverlay.displayName = SheetPrimitive.Overlay.displayName;
const sheetVariants = cva(
"fixed z-50 gap-4 bg-background p-6 shadow-lg transition ease-in-out data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:duration-300 data-[state=open]:duration-500",
{
variants: {
side: {
top: "inset-x-0 top-0 border-b data-[state=closed]:slide-out-to-top data-[state=open]:slide-in-from-top",
bottom:
"inset-x-0 bottom-0 border-t data-[state=closed]:slide-out-to-bottom data-[state=open]:slide-in-from-bottom",
left: "inset-y-0 left-0 h-full w-3/4 border-r data-[state=closed]:slide-out-to-left data-[state=open]:slide-in-from-left sm:max-w-sm",
right:
"inset-y-0 right-0 h-full w-3/4 border-l data-[state=closed]:slide-out-to-right data-[state=open]:slide-in-from-right sm:max-w-sm",
},
},
defaultVariants: {
side: "right",
},
}
);
interface SheetContentProps
extends React.ComponentPropsWithoutRef<typeof SheetPrimitive.Content>,
VariantProps<typeof sheetVariants> {}
const SheetContent = React.forwardRef<React.ElementRef<typeof SheetPrimitive.Content>, SheetContentProps>(
({ side = "right", className, children, ...props }, ref) => (
<SheetPortal>
<SheetOverlay />
<SheetPrimitive.Content ref={ref} className={classNames(sheetVariants({ side }), className)} {...props}>
{children}
<SheetPrimitive.Close className="ring-offset-background focus:ring-ring data-[state=open]:bg-secondary absolute right-4 top-4 rounded-sm opacity-70 transition-opacity hover:opacity-100 focus:outline-none focus:ring-2 focus:ring-offset-2 disabled:pointer-events-none">
<X className="h-4 w-4" />
<span className="sr-only">Close</span>
</SheetPrimitive.Close>
</SheetPrimitive.Content>
</SheetPortal>
)
);
SheetContent.displayName = SheetPrimitive.Content.displayName;
const SheetHeader = ({ className, ...props }: React.HTMLAttributes<HTMLDivElement>) => (
<div className={classNames("flex flex-col space-y-2 text-center sm:text-left", className)} {...props} />
);
SheetHeader.displayName = "SheetHeader";
const SheetFooter = ({ className, ...props }: React.HTMLAttributes<HTMLDivElement>) => (
<div
className={classNames("flex flex-col-reverse sm:flex-row sm:justify-end sm:space-x-2", className)}
{...props}
/>
);
SheetFooter.displayName = "SheetFooter";
const SheetTitle = React.forwardRef<
React.ElementRef<typeof SheetPrimitive.Title>,
React.ComponentPropsWithoutRef<typeof SheetPrimitive.Title>
>(({ className, ...props }, ref) => (
<SheetPrimitive.Title
ref={ref}
className={classNames("text-foreground text-lg font-semibold", className)}
{...props}
/>
));
SheetTitle.displayName = SheetPrimitive.Title.displayName;
const SheetDescription = React.forwardRef<
React.ElementRef<typeof SheetPrimitive.Description>,
React.ComponentPropsWithoutRef<typeof SheetPrimitive.Description>
>(({ className, ...props }, ref) => (
<SheetPrimitive.Description
ref={ref}
className={classNames("text-muted-foreground text-sm", className)}
{...props}
/>
));
SheetDescription.displayName = SheetPrimitive.Description.displayName;
export {
Sheet,
SheetClose,
SheetContent,
SheetDescription,
SheetFooter,
SheetHeader,
SheetOverlay,
SheetPortal,
SheetTitle,
SheetTrigger,
};

View File

@@ -1,85 +0,0 @@
import * as React from "react";
import { classNames } from "../../lib/utils";
const Table = React.forwardRef<HTMLTableElement, React.HTMLAttributes<HTMLTableElement>>(
({ className, ...props }, ref) => (
<div className="relative w-full overflow-auto">
<table ref={ref} className={classNames("w-full caption-bottom text-sm", className)} {...props} />
</div>
)
);
Table.displayName = "Table";
const TableHeader = React.forwardRef<HTMLTableSectionElement, React.HTMLAttributes<HTMLTableSectionElement>>(
({ className, ...props }, ref) => (
<thead ref={ref} className={classNames("[&_tr]:border-b", className)} {...props} />
)
);
TableHeader.displayName = "TableHeader";
const TableBody = React.forwardRef<HTMLTableSectionElement, React.HTMLAttributes<HTMLTableSectionElement>>(
({ className, ...props }, ref) => (
<tbody ref={ref} className={classNames("[&_tr:last-child]:border-0", className)} {...props} />
)
);
TableBody.displayName = "TableBody";
const TableFooter = React.forwardRef<HTMLTableSectionElement, React.HTMLAttributes<HTMLTableSectionElement>>(
({ className, ...props }, ref) => (
<tfoot
ref={ref}
className={classNames("bg-muted/50 border-t font-medium [&>tr]:last:border-b-0", className)}
{...props}
/>
)
);
TableFooter.displayName = "TableFooter";
const TableRow = React.forwardRef<HTMLTableRowElement, React.HTMLAttributes<HTMLTableRowElement>>(
({ className, ...props }, ref) => (
<tr
ref={ref}
className={classNames(
"hover:bg-muted/50 data-[state=selected]:bg-muted border-b transition-colors",
className
)}
{...props}
/>
)
);
TableRow.displayName = "TableRow";
const TableHead = React.forwardRef<HTMLTableCellElement, React.ThHTMLAttributes<HTMLTableCellElement>>(
({ className, ...props }, ref) => (
<th
ref={ref}
className={classNames(
"text-muted-foreground h-12 px-4 text-left align-middle font-medium [&:has([role=checkbox])]:pr-0",
className
)}
{...props}
/>
)
);
TableHead.displayName = "TableHead";
const TableCell = React.forwardRef<HTMLTableCellElement, React.TdHTMLAttributes<HTMLTableCellElement>>(
({ className, ...props }, ref) => (
<td
ref={ref}
className={classNames("p-4 align-middle [&:has([role=checkbox])]:pr-0", className)}
{...props}
/>
)
);
TableCell.displayName = "TableCell";
const TableCaption = React.forwardRef<HTMLTableCaptionElement, React.HTMLAttributes<HTMLTableCaptionElement>>(
({ className, ...props }, ref) => (
<caption ref={ref} className={classNames("text-muted-foreground mt-4 text-sm", className)} {...props} />
)
);
TableCaption.displayName = "TableCaption";
export { Table, TableBody, TableCaption, TableCell, TableFooter, TableHead, TableHeader, TableRow };

View File

@@ -1,55 +0,0 @@
"use client";
import * as TabsPrimitive from "@radix-ui/react-tabs";
import * as React from "react";
import { classNames } from "../../lib/utils";
const Tabs = TabsPrimitive.Root;
const TabsList = React.forwardRef<
React.ElementRef<typeof TabsPrimitive.List>,
React.ComponentPropsWithoutRef<typeof TabsPrimitive.List>
>(({ className, ...props }, ref) => (
<TabsPrimitive.List
ref={ref}
className={classNames(
"bg-muted text-muted-foreground inline-flex h-10 items-center justify-center rounded-md p-1",
className
)}
{...props}
/>
));
TabsList.displayName = TabsPrimitive.List.displayName;
const TabsTrigger = React.forwardRef<
React.ElementRef<typeof TabsPrimitive.Trigger>,
React.ComponentPropsWithoutRef<typeof TabsPrimitive.Trigger>
>(({ className, ...props }, ref) => (
<TabsPrimitive.Trigger
ref={ref}
className={classNames(
"ring-offset-background focus-visible:ring-ring data-[state=active]:bg-background data-[state=active]:text-foreground inline-flex items-center justify-center whitespace-nowrap rounded-sm px-3 py-1.5 text-sm font-medium transition-all focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-offset-2 disabled:pointer-events-none disabled:opacity-50 data-[state=active]:shadow-sm",
className
)}
{...props}
/>
));
TabsTrigger.displayName = TabsPrimitive.Trigger.displayName;
const TabsContent = React.forwardRef<
React.ElementRef<typeof TabsPrimitive.Content>,
React.ComponentPropsWithoutRef<typeof TabsPrimitive.Content>
>(({ className, ...props }, ref) => (
<TabsPrimitive.Content
ref={ref}
className={classNames(
"ring-offset-background focus-visible:ring-ring mt-2 focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-offset-2",
className
)}
{...props}
/>
));
TabsContent.displayName = TabsPrimitive.Content.displayName;
export { Tabs, TabsContent, TabsList, TabsTrigger };

View File

@@ -1,30 +0,0 @@
"use client";
import * as TooltipPrimitive from "@radix-ui/react-tooltip";
import * as React from "react";
import { classNames } from "../../lib/utils";
const TooltipProvider = TooltipPrimitive.Provider;
const Tooltip = TooltipPrimitive.Root;
const TooltipTrigger = TooltipPrimitive.Trigger;
const TooltipContent = React.forwardRef<
React.ElementRef<typeof TooltipPrimitive.Content>,
React.ComponentPropsWithoutRef<typeof TooltipPrimitive.Content>
>(({ className, sideOffset = 4, ...props }, ref) => (
<TooltipPrimitive.Content
ref={ref}
sideOffset={sideOffset}
className={classNames(
"bg-popover text-popover-foreground animate-in fade-in-0 zoom-in-95 data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=closed]:zoom-out-95 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2 z-50 overflow-hidden rounded-md border px-3 py-1.5 text-sm shadow-md",
className
)}
{...props}
/>
));
TooltipContent.displayName = TooltipPrimitive.Content.displayName;
export { Tooltip, TooltipContent, TooltipProvider, TooltipTrigger };

View File

@@ -1,3 +1,3 @@
export const classNames = (...classes: any) => {
export function classNames(...classes: any) {
return classes.filter(Boolean).join(" ");
};
}

View File

@@ -13,21 +13,13 @@
"dependencies": {
"@formbricks/js": "workspace:*",
"@formbricks/ui": "workspace:*",
"@radix-ui/react-dialog": "^1.0.5",
"@radix-ui/react-dropdown-menu": "^2.0.6",
"@radix-ui/react-progress": "^1.0.3",
"@radix-ui/react-separator": "^1.0.3",
"@radix-ui/react-slot": "^1.0.2",
"@radix-ui/react-tabs": "^1.0.4",
"@radix-ui/react-tooltip": "^1.0.7",
"classnames": "^2.5.1",
"lucide-react": "^0.378.0",
"next": "14.2.3",
"react": "18.3.1",
"react-dom": "18.3.1"
},
"devDependencies": {
"@formbricks/tsconfig": "workspace:*",
"eslint-config-formbricks": "workspace:*"
"eslint-config-formbricks": "workspace:*",
"@formbricks/tsconfig": "workspace:*"
}
}

View File

@@ -3,7 +3,7 @@ import Head from "next/head";
import "../styles/globals.css";
const App = ({ Component, pageProps }: AppProps) => {
export default function App({ Component, pageProps }: AppProps) {
return (
<>
<Head>
@@ -18,6 +18,4 @@ const App = ({ Component, pageProps }: AppProps) => {
<Component {...pageProps} />
</>
);
};
export default App;
}

View File

@@ -1,6 +1,6 @@
import { Head, Html, Main, NextScript } from "next/document";
const Document = () => {
export default function Document() {
return (
<Html lang="en" className="h-full bg-slate-50">
<Head />
@@ -10,6 +10,4 @@ const Document = () => {
</body>
</Html>
);
};
export default Document;
}

View File

@@ -9,7 +9,7 @@ import fbsetup from "../../public/fb-setup.png";
declare const window: any;
const AppPage = ({}) => {
export default function AppPage({}) {
const [darkMode, setDarkMode] = useState(false);
const router = useRouter();
@@ -36,11 +36,7 @@ const AppPage = ({}) => {
if (process.env.NEXT_PUBLIC_FORMBRICKS_ENVIRONMENT_ID && process.env.NEXT_PUBLIC_FORMBRICKS_API_HOST) {
const userId = "THIS-IS-A-VERY-LONG-USER-ID-FOR-TESTING";
const userInitAttributes = {
language: "de",
"Init Attribute 1": "eight",
"Init Attribute 2": "two",
};
const userInitAttributes = { language: "de", "Init Attribute 1": "eight", "Init Attribute 2": "two" };
formbricks.init({
environmentId: process.env.NEXT_PUBLIC_FORMBRICKS_ENVIRONMENT_ID,
@@ -238,6 +234,4 @@ const AppPage = ({}) => {
</div>
</div>
);
};
export default AppPage;
}

View File

@@ -1,663 +0,0 @@
import {
ChevronLeft,
ChevronRight,
Copy,
CreditCard,
File,
Home,
LineChart,
ListFilter,
MoreVertical,
Package,
Package2,
PanelLeft,
Search,
Settings,
ShoppingCart,
Truck,
Users2,
} from "lucide-react";
import Image from "next/image";
import Link from "next/link";
import { useRouter } from "next/router";
import { useEffect } from "react";
import formbricks from "@formbricks/js/app";
import { Badge } from "../../components/ui/badge";
import {
Breadcrumb,
BreadcrumbItem,
BreadcrumbLink,
BreadcrumbList,
BreadcrumbPage,
BreadcrumbSeparator,
} from "../../components/ui/breadcrumb";
import { Button } from "../../components/ui/button";
import {
Card,
CardContent,
CardDescription,
CardFooter,
CardHeader,
CardTitle,
} from "../../components/ui/card";
import {
DropdownMenu,
DropdownMenuCheckboxItem,
DropdownMenuContent,
DropdownMenuItem,
DropdownMenuLabel,
DropdownMenuSeparator,
DropdownMenuTrigger,
} from "../../components/ui/dropdown-menu";
import { Input } from "../../components/ui/input";
import { Pagination, PaginationContent, PaginationItem } from "../../components/ui/pagination";
import { Progress } from "../../components/ui/progress";
import { Separator } from "../../components/ui/separator";
import { Sheet, SheetContent, SheetTrigger } from "../../components/ui/sheet";
import { Table, TableBody, TableCell, TableHead, TableHeader, TableRow } from "../../components/ui/table";
import { Tabs, TabsContent, TabsList, TabsTrigger } from "../../components/ui/tabs";
import { Tooltip, TooltipContent, TooltipProvider, TooltipTrigger } from "../../components/ui/tooltip";
declare const window: any;
const SaaSPage = ({}) => {
const router = useRouter();
useEffect(() => {
// enable Formbricks debug mode by adding formbricksDebug=true GET parameter
const addFormbricksDebugParam = () => {
const urlParams = new URLSearchParams(window.location.search);
if (!urlParams.has("formbricksDebug")) {
urlParams.set("formbricksDebug", "true");
const newUrl = `${window.location.pathname}?${urlParams.toString()}`;
window.history.replaceState({}, "", newUrl);
}
};
addFormbricksDebugParam();
if (process.env.NEXT_PUBLIC_FORMBRICKS_ENVIRONMENT_ID && process.env.NEXT_PUBLIC_FORMBRICKS_API_HOST) {
const userId = "THIS-IS-A-VERY-LONG-USER-ID-FOR-TESTING";
const userInitAttributes = {
language: "de",
"Init Attribute 1": "eight",
"Init Attribute 2": "two",
};
formbricks.init({
environmentId: process.env.NEXT_PUBLIC_FORMBRICKS_ENVIRONMENT_ID,
apiHost: process.env.NEXT_PUBLIC_FORMBRICKS_API_HOST,
userId,
attributes: userInitAttributes,
});
}
// Connect next.js router to Formbricks
if (process.env.NEXT_PUBLIC_FORMBRICKS_ENVIRONMENT_ID && process.env.NEXT_PUBLIC_FORMBRICKS_API_HOST) {
const handleRouteChange = formbricks?.registerRouteChange;
router.events.on("routeChangeComplete", handleRouteChange);
return () => {
router.events.off("routeChangeComplete", handleRouteChange);
};
}
});
return (
<div className="bg-muted/40 flex min-h-screen w-full flex-col">
<TooltipProvider delayDuration={10}>
<aside className="bg-background fixed inset-y-0 left-0 z-10 hidden w-14 flex-col border-r sm:flex">
<nav className="flex flex-col items-center gap-4 px-2 sm:py-5">
<Link
href="#"
className="bg-primary text-primary-foreground group flex h-9 w-9 shrink-0 items-center justify-center gap-2 rounded-full text-lg font-semibold md:h-8 md:w-8 md:text-base">
<Package2 className="h-4 w-4 transition-all group-hover:scale-110" />
<span className="sr-only">Acme Inc</span>
</Link>
<Tooltip>
<TooltipTrigger asChild>
<Link
href="#"
className="text-muted-foreground hover:text-foreground flex h-9 w-9 items-center justify-center rounded-lg transition-colors md:h-8 md:w-8">
<Home className="h-5 w-5" />
<span className="sr-only">Dashboard</span>
</Link>
</TooltipTrigger>
<TooltipContent side="right">Dashboard</TooltipContent>
</Tooltip>
<Tooltip>
<TooltipTrigger asChild>
<Link
href="#"
className="bg-accent text-accent-foreground hover:text-foreground flex h-9 w-9 items-center justify-center rounded-lg transition-colors md:h-8 md:w-8">
<ShoppingCart className="h-5 w-5" />
<span className="sr-only">Orders</span>
</Link>
</TooltipTrigger>
<TooltipContent side="right">Orders</TooltipContent>
</Tooltip>
<Tooltip>
<TooltipTrigger asChild>
<Link
href="#"
className="text-muted-foreground hover:text-foreground flex h-9 w-9 items-center justify-center rounded-lg transition-colors md:h-8 md:w-8">
<Package className="h-5 w-5" />
<span className="sr-only">Products</span>
</Link>
</TooltipTrigger>
<TooltipContent side="right">Products</TooltipContent>
</Tooltip>
<Tooltip>
<TooltipTrigger asChild>
<Link
href="#"
className="text-muted-foreground hover:text-foreground flex h-9 w-9 items-center justify-center rounded-lg transition-colors md:h-8 md:w-8">
<Users2 className="h-5 w-5" />
<span className="sr-only">Customers</span>
</Link>
</TooltipTrigger>
<TooltipContent side="right">Customers</TooltipContent>
</Tooltip>
<Tooltip>
<TooltipTrigger asChild>
<Link
href="#"
className="text-muted-foreground hover:text-foreground flex h-9 w-9 items-center justify-center rounded-lg transition-colors md:h-8 md:w-8">
<LineChart className="h-5 w-5" />
<span className="sr-only">Analytics</span>
</Link>
</TooltipTrigger>
<TooltipContent side="right">Analytics</TooltipContent>
</Tooltip>
</nav>
<nav className="mt-auto flex flex-col items-center gap-4 px-2 sm:py-5">
<Tooltip>
<TooltipTrigger asChild>
<Link
href="#"
className="text-muted-foreground hover:text-foreground flex h-9 w-9 items-center justify-center rounded-lg transition-colors md:h-8 md:w-8">
<Settings className="h-5 w-5" />
<span className="sr-only">Settings</span>
</Link>
</TooltipTrigger>
<TooltipContent side="right">Settings</TooltipContent>
</Tooltip>
</nav>
</aside>
<div className="flex flex-col sm:gap-4 sm:py-4 sm:pl-14">
<header className="bg-background sticky top-0 z-30 flex h-14 items-center gap-4 border-b px-4 sm:static sm:h-auto sm:border-0 sm:bg-transparent sm:px-6">
<Sheet>
<SheetTrigger asChild>
<Button size="icon" variant="outline" className="sm:hidden">
<PanelLeft className="h-5 w-5" />
<span className="sr-only">Toggle Menu</span>
</Button>
</SheetTrigger>
<SheetContent side="left" className="sm:max-w-xs">
<nav className="grid gap-6 text-lg font-medium">
<Link
href="#"
className="bg-primary text-primary-foreground group flex h-10 w-10 shrink-0 items-center justify-center gap-2 rounded-full text-lg font-semibold md:text-base">
<Package2 className="h-5 w-5 transition-all group-hover:scale-110" />
<span className="sr-only">Acme Inc</span>
</Link>
<Link
href="#"
className="text-muted-foreground hover:text-foreground flex items-center gap-4 px-2.5">
<Home className="h-5 w-5" />
Dashboard
</Link>
<Link href="#" className="text-foreground flex items-center gap-4 px-2.5">
<ShoppingCart className="h-5 w-5" />
Orders
</Link>
<Link
href="#"
className="text-muted-foreground hover:text-foreground flex items-center gap-4 px-2.5">
<Package className="h-5 w-5" />
Products
</Link>
<Link
href="#"
className="text-muted-foreground hover:text-foreground flex items-center gap-4 px-2.5">
<Users2 className="h-5 w-5" />
Customers
</Link>
<Link
href="#"
className="text-muted-foreground hover:text-foreground flex items-center gap-4 px-2.5">
<LineChart className="h-5 w-5" />
Settings
</Link>
</nav>
</SheetContent>
</Sheet>
<Breadcrumb className="hidden md:flex">
<BreadcrumbList>
<BreadcrumbItem>
<BreadcrumbLink asChild>
<Link href="#">Dashboard</Link>
</BreadcrumbLink>
</BreadcrumbItem>
<BreadcrumbSeparator />
<BreadcrumbItem>
<BreadcrumbLink asChild>
<Link href="#">Orders</Link>
</BreadcrumbLink>
</BreadcrumbItem>
<BreadcrumbSeparator />
<BreadcrumbItem>
<BreadcrumbPage>Recent Orders</BreadcrumbPage>
</BreadcrumbItem>
</BreadcrumbList>
</Breadcrumb>
<div className="relative ml-auto flex-1 md:grow-0">
<Search className="text-muted-foreground absolute left-2.5 top-2.5 h-4 w-4" />
<Input
type="search"
placeholder="Search..."
className="bg-background w-full rounded-lg pl-8 md:w-[200px] lg:w-[336px]"
/>
</div>
<DropdownMenu>
<DropdownMenuTrigger asChild>
<Button variant="outline" size="icon" className="overflow-hidden rounded-full">
<Image
src="/user-avatar.png"
width={36}
height={36}
alt="Avatar"
className="overflow-hidden rounded-full"
/>
</Button>
</DropdownMenuTrigger>
<DropdownMenuContent align="end">
<DropdownMenuLabel>My Account</DropdownMenuLabel>
<DropdownMenuSeparator />
<DropdownMenuItem>Settings</DropdownMenuItem>
<DropdownMenuItem>Support</DropdownMenuItem>
<DropdownMenuSeparator />
<DropdownMenuItem>Logout</DropdownMenuItem>
</DropdownMenuContent>
</DropdownMenu>
</header>
<main className="grid flex-1 items-start gap-4 p-4 sm:px-6 sm:py-0 md:gap-8 lg:grid-cols-3 xl:grid-cols-3">
<div className="grid auto-rows-max items-start gap-4 md:gap-8 lg:col-span-2">
<div className="grid gap-4 sm:grid-cols-2 md:grid-cols-4 lg:grid-cols-2 xl:grid-cols-4">
<Card className="sm:col-span-2" x-chunk="dashboard-05-chunk-0">
<CardHeader className="pb-3">
<CardTitle>Your Orders</CardTitle>
<CardDescription className="max-w-lg text-balance leading-relaxed">
Introducing Our Dynamic Orders Dashboard for Seamless Management and Insightful
Analysis.
</CardDescription>
</CardHeader>
<CardFooter>
<Button>Create New Order</Button>
</CardFooter>
</Card>
<Card x-chunk="dashboard-05-chunk-1">
<CardHeader className="pb-2">
<CardDescription>This Week</CardDescription>
<CardTitle className="text-4xl">$1,329</CardTitle>
</CardHeader>
<CardContent>
<div className="text-muted-foreground text-xs">+25% from last week</div>
</CardContent>
<CardFooter>
<Progress value={25} aria-label="25% increase" />
</CardFooter>
</Card>
<Card x-chunk="dashboard-05-chunk-2">
<CardHeader className="pb-2">
<CardDescription>This Month</CardDescription>
<CardTitle className="text-4xl">$5,329</CardTitle>
</CardHeader>
<CardContent>
<div className="text-muted-foreground text-xs">+10% from last month</div>
</CardContent>
<CardFooter>
<Progress value={12} aria-label="12% increase" />
</CardFooter>
</Card>
</div>
<Tabs defaultValue="week">
<div className="flex items-center">
<TabsList>
<TabsTrigger value="week">Week</TabsTrigger>
<TabsTrigger value="month">Month</TabsTrigger>
<TabsTrigger value="year">Year</TabsTrigger>
</TabsList>
<div className="ml-auto flex items-center gap-2">
<DropdownMenu>
<DropdownMenuTrigger asChild>
<Button variant="outline" size="sm" className="h-7 gap-1 text-sm">
<ListFilter className="h-3.5 w-3.5" />
<span className="sr-only sm:not-sr-only">Filter</span>
</Button>
</DropdownMenuTrigger>
<DropdownMenuContent align="end">
<DropdownMenuLabel>Filter by</DropdownMenuLabel>
<DropdownMenuSeparator />
<DropdownMenuCheckboxItem checked>Fulfilled</DropdownMenuCheckboxItem>
<DropdownMenuCheckboxItem>Declined</DropdownMenuCheckboxItem>
<DropdownMenuCheckboxItem>Refunded</DropdownMenuCheckboxItem>
</DropdownMenuContent>
</DropdownMenu>
<Button size="sm" variant="outline" className="h-7 gap-1 text-sm">
<File className="h-3.5 w-3.5" />
<span className="sr-only sm:not-sr-only">Export</span>
</Button>
</div>
</div>
<TabsContent value="week">
<Card x-chunk="dashboard-05-chunk-3">
<CardHeader className="px-7">
<CardTitle>Orders</CardTitle>
<CardDescription>Recent orders from your store.</CardDescription>
</CardHeader>
<CardContent>
<Table>
<TableHeader>
<TableRow>
<TableHead>Customer</TableHead>
<TableHead className="hidden sm:table-cell">Type</TableHead>
<TableHead className="hidden sm:table-cell">Status</TableHead>
<TableHead className="hidden md:table-cell">Date</TableHead>
<TableHead className="text-right">Amount</TableHead>
</TableRow>
</TableHeader>
<TableBody>
<TableRow className="bg-accent">
<TableCell>
<div className="font-medium">Liam Johnson</div>
<div className="text-muted-foreground hidden text-sm md:inline">
liam@example.com
</div>
</TableCell>
<TableCell className="hidden sm:table-cell">Sale</TableCell>
<TableCell className="hidden sm:table-cell">
<Badge className="text-xs" variant="secondary">
Fulfilled
</Badge>
</TableCell>
<TableCell className="hidden md:table-cell">2023-06-23</TableCell>
<TableCell className="text-right">$250.00</TableCell>
</TableRow>
<TableRow>
<TableCell>
<div className="font-medium">Olivia Smith</div>
<div className="text-muted-foreground hidden text-sm md:inline">
olivia@example.com
</div>
</TableCell>
<TableCell className="hidden sm:table-cell">Refund</TableCell>
<TableCell className="hidden sm:table-cell">
<Badge className="text-xs" variant="outline">
Declined
</Badge>
</TableCell>
<TableCell className="hidden md:table-cell">2023-06-24</TableCell>
<TableCell className="text-right">$150.00</TableCell>
</TableRow>
<TableRow>
<TableCell>
<div className="font-medium">Noah Williams</div>
<div className="text-muted-foreground hidden text-sm md:inline">
noah@example.com
</div>
</TableCell>
<TableCell className="hidden sm:table-cell">Subscription</TableCell>
<TableCell className="hidden sm:table-cell">
<Badge className="text-xs" variant="secondary">
Fulfilled
</Badge>
</TableCell>
<TableCell className="hidden md:table-cell">2023-06-25</TableCell>
<TableCell className="text-right">$350.00</TableCell>
</TableRow>
<TableRow>
<TableCell>
<div className="font-medium">Emma Brown</div>
<div className="text-muted-foreground hidden text-sm md:inline">
emma@example.com
</div>
</TableCell>
<TableCell className="hidden sm:table-cell">Sale</TableCell>
<TableCell className="hidden sm:table-cell">
<Badge className="text-xs" variant="secondary">
Fulfilled
</Badge>
</TableCell>
<TableCell className="hidden md:table-cell">2023-06-26</TableCell>
<TableCell className="text-right">$450.00</TableCell>
</TableRow>
<TableRow>
<TableCell>
<div className="font-medium">Liam Johnson</div>
<div className="text-muted-foreground hidden text-sm md:inline">
liam@example.com
</div>
</TableCell>
<TableCell className="hidden sm:table-cell">Sale</TableCell>
<TableCell className="hidden sm:table-cell">
<Badge className="text-xs" variant="secondary">
Fulfilled
</Badge>
</TableCell>
<TableCell className="hidden md:table-cell">2023-06-23</TableCell>
<TableCell className="text-right">$250.00</TableCell>
</TableRow>
<TableRow>
<TableCell>
<div className="font-medium">Liam Johnson</div>
<div className="text-muted-foreground hidden text-sm md:inline">
liam@example.com
</div>
</TableCell>
<TableCell className="hidden sm:table-cell">Sale</TableCell>
<TableCell className="hidden sm:table-cell">
<Badge className="text-xs" variant="secondary">
Fulfilled
</Badge>
</TableCell>
<TableCell className="hidden md:table-cell">2023-06-23</TableCell>
<TableCell className="text-right">$250.00</TableCell>
</TableRow>
<TableRow>
<TableCell>
<div className="font-medium">Olivia Smith</div>
<div className="text-muted-foreground hidden text-sm md:inline">
olivia@example.com
</div>
</TableCell>
<TableCell className="hidden sm:table-cell">Refund</TableCell>
<TableCell className="hidden sm:table-cell">
<Badge className="text-xs" variant="outline">
Declined
</Badge>
</TableCell>
<TableCell className="hidden md:table-cell">2023-06-24</TableCell>
<TableCell className="text-right">$150.00</TableCell>
</TableRow>
<TableRow>
<TableCell>
<div className="font-medium">Emma Brown</div>
<div className="text-muted-foreground hidden text-sm md:inline">
emma@example.com
</div>
</TableCell>
<TableCell className="hidden sm:table-cell">Sale</TableCell>
<TableCell className="hidden sm:table-cell">
<Badge className="text-xs" variant="secondary">
Fulfilled
</Badge>
</TableCell>
<TableCell className="hidden md:table-cell">2023-06-26</TableCell>
<TableCell className="text-right">$450.00</TableCell>
</TableRow>
</TableBody>
</Table>
</CardContent>
</Card>
</TabsContent>
</Tabs>
</div>
<div>
<Card className="overflow-hidden" x-chunk="dashboard-05-chunk-4">
<CardHeader className="bg-muted/50 flex flex-row items-start">
<div className="grid gap-0.5">
<CardTitle className="group flex items-center gap-2 text-lg">
Order Oe31b70H
<Button
size="icon"
variant="outline"
className="h-6 w-6 opacity-0 transition-opacity group-hover:opacity-100">
<Copy className="h-3 w-3" />
<span className="sr-only">Copy Order ID</span>
</Button>
</CardTitle>
<CardDescription>Date: November 23, 2023</CardDescription>
</div>
<div className="ml-auto flex items-center gap-1">
<Button size="sm" variant="outline" className="h-8 gap-1">
<Truck className="h-3.5 w-3.5" />
<span className="lg:sr-only xl:not-sr-only xl:whitespace-nowrap">Track Order</span>
</Button>
<DropdownMenu>
<DropdownMenuTrigger asChild>
<Button size="icon" variant="outline" className="h-8 w-8">
<MoreVertical className="h-3.5 w-3.5" />
<span className="sr-only">More</span>
</Button>
</DropdownMenuTrigger>
<DropdownMenuContent align="end">
<DropdownMenuItem>Edit</DropdownMenuItem>
<DropdownMenuItem>Export</DropdownMenuItem>
<DropdownMenuSeparator />
<DropdownMenuItem>Trash</DropdownMenuItem>
</DropdownMenuContent>
</DropdownMenu>
</div>
</CardHeader>
<CardContent className="p-6 text-sm">
<div className="grid gap-3">
<div className="font-semibold">Order Details</div>
<ul className="grid gap-3">
<li className="flex items-center justify-between">
<span className="text-muted-foreground">
Glimmer Lamps x <span>2</span>
</span>
<span>$250.00</span>
</li>
<li className="flex items-center justify-between">
<span className="text-muted-foreground">
Aqua Filters x <span>1</span>
</span>
<span>$49.00</span>
</li>
</ul>
<Separator className="my-2" />
<ul className="grid gap-3">
<li className="flex items-center justify-between">
<span className="text-muted-foreground">Subtotal</span>
<span>$299.00</span>
</li>
<li className="flex items-center justify-between">
<span className="text-muted-foreground">Shipping</span>
<span>$5.00</span>
</li>
<li className="flex items-center justify-between">
<span className="text-muted-foreground">Tax</span>
<span>$25.00</span>
</li>
<li className="flex items-center justify-between font-semibold">
<span className="text-muted-foreground">Total</span>
<span>$329.00</span>
</li>
</ul>
</div>
<Separator className="my-4" />
<div className="grid grid-cols-2 gap-4">
<div className="grid gap-3">
<div className="font-semibold">Shipping Information</div>
<address className="text-muted-foreground grid gap-0.5 not-italic">
<span>Liam Johnson</span>
<span>1234 Main St.</span>
<span>Anytown, CA 12345</span>
</address>
</div>
<div className="grid auto-rows-max gap-3">
<div className="font-semibold">Billing Information</div>
<div className="text-muted-foreground">Same as shipping address</div>
</div>
</div>
<Separator className="my-4" />
<div className="grid gap-3">
<div className="font-semibold">Customer Information</div>
<dl className="grid gap-3">
<div className="flex items-center justify-between">
<dt className="text-muted-foreground">Customer</dt>
<dd>Liam Johnson</dd>
</div>
<div className="flex items-center justify-between">
<dt className="text-muted-foreground">Email</dt>
<dd>
<a href="mailto:">liam@acme.com</a>
</dd>
</div>
<div className="flex items-center justify-between">
<dt className="text-muted-foreground">Phone</dt>
<dd>
<a href="tel:">+1 234 567 890</a>
</dd>
</div>
</dl>
</div>
<Separator className="my-4" />
<div className="grid gap-3">
<div className="font-semibold">Payment Information</div>
<dl className="grid gap-3">
<div className="flex items-center justify-between">
<dt className="text-muted-foreground flex items-center gap-1">
<CreditCard className="h-4 w-4" />
Visa
</dt>
<dd>**** **** **** 4532</dd>
</div>
</dl>
</div>
</CardContent>
<CardFooter className="bg-muted/50 flex flex-row items-center border-t px-6 py-3">
<div className="text-muted-foreground text-xs">
Updated <time dateTime="2023-11-23">November 23, 2023</time>
</div>
<Pagination className="ml-auto mr-0 w-auto">
<PaginationContent>
<PaginationItem>
<Button size="icon" variant="outline" className="h-6 w-6">
<ChevronLeft className="h-3.5 w-3.5" />
<span className="sr-only">Previous Order</span>
</Button>
</PaginationItem>
<PaginationItem>
<Button size="icon" variant="outline" className="h-6 w-6">
<ChevronRight className="h-3.5 w-3.5" />
<span className="sr-only">Next Order</span>
</Button>
</PaginationItem>
</PaginationContent>
</Pagination>
</CardFooter>
</Card>
</div>
</main>
</div>
</TooltipProvider>
</div>
);
};
export default SaaSPage;

View File

@@ -9,7 +9,7 @@ import fbsetup from "../../public/fb-setup.png";
declare const window: any;
const AppPage = ({}) => {
export default function AppPage({}) {
const [darkMode, setDarkMode] = useState(false);
const router = useRouter();
@@ -139,6 +139,4 @@ const AppPage = ({}) => {
</div>
</div>
);
};
export default AppPage;
}

Binary file not shown.

Before

Width:  |  Height:  |  Size: 30 KiB

View File

@@ -33,7 +33,7 @@ const libraries = [
},
];
export const Libraries = () => {
export function Libraries() {
return (
<div className="my-16 xl:max-w-none">
<div className="not-prose mt-4 grid grid-cols-1 gap-x-6 gap-y-10 border-slate-900/5 sm:grid-cols-2 xl:max-w-none xl:grid-cols-3 dark:border-white/5">
@@ -57,4 +57,4 @@ export const Libraries = () => {
</div>
</div>
);
};
}

View File

@@ -80,11 +80,6 @@ formbricks.init({
You can use the setAttribute function to set any custom attribute for the user (e.g. name, plan, etc.):
<Note>
Please note that the number of different attribute classes (e.g., "Plan," "First Name," etc.) is currently
limited to 150 attributes per environment.
</Note>
<Col>
<CodeGroup title="Setting Custom Attributes">
@@ -120,4 +115,4 @@ formbricks.logout();
```
</CodeGroup>
</Col>
</Col>

View File

@@ -135,7 +135,7 @@ import { Popover, PopoverContent, PopoverTrigger } from "@formbricks/ui/Popover"
import { handleFeedbackSubmit, updateFeedback } from "../../lib/handleFeedbackSubmit";
export const DocsFeedback = () => {
export default function DocsFeedback() {
const router = useRouter();
const [isOpen, setIsOpen] = useState(false);
const [sharedFeedback, setSharedFeedback] = useState(false);
@@ -199,7 +199,7 @@ export const DocsFeedback = () => {
)}
</div>
);
};
}
```
</CodeGroup>

View File

@@ -1,6 +1,6 @@
import { Accordion, AccordionContent, AccordionItem, AccordionTrigger } from "@formbricks/ui/Accordion";
import { FaqJsonLdComponent } from "./FAQPageJsonLd";
import FaqJsonLdComponent from "./FAQPageJsonLd";
const FAQ_DATA = [
{
@@ -62,7 +62,7 @@ export const faqJsonLdData = FAQ_DATA.map((faq) => ({
acceptedAnswerText: faq.answer(),
}));
export const FAQ = () => {
export default function FAQ() {
return (
<>
<FaqJsonLdComponent data={faqJsonLdData} />
@@ -76,4 +76,4 @@ export const FAQ = () => {
</Accordion>
</>
);
};
}

View File

@@ -2,11 +2,11 @@
import { FAQPageJsonLd } from "next-seo";
export const FaqJsonLdComponent = ({ data }) => {
export default function FaqJsonLdComponent({ data }) {
const faqEntities = data.map(({ question, answer }) => ({
questionName: question,
acceptedAnswerText: answer,
}));
return <FAQPageJsonLd mainEntity={faqEntities} />;
};
}

View File

@@ -26,7 +26,7 @@ const gettingStarted = [
},
];
export const GettingStarted = () => {
export function GettingStarted() {
return (
<div className="my-16 xl:max-w-none">
<Heading level={2} id="getting-started">
@@ -47,4 +47,4 @@ export const GettingStarted = () => {
</div>
</div>
);
};
}

View File

@@ -15,7 +15,7 @@ export const metadata: Metadata = {
const jost = Jost({ subsets: ["latin"] });
const RootLayout = async ({ children }: { children: React.ReactNode }) => {
export default async function RootLayout({ children }: { children: React.ReactNode }) {
let pages = await glob("**/*.mdx", { cwd: "src/app" });
let allSectionsEntries = (await Promise.all(
pages.map(async (filename) => [
@@ -36,6 +36,4 @@ const RootLayout = async ({ children }: { children: React.ReactNode }) => {
</body>
</html>
);
};
export default RootLayout;
}

View File

@@ -1,7 +1,7 @@
import { Button } from "@/components/Button";
import { HeroPattern } from "@/components/HeroPattern";
const NotFound = () => {
export default function NotFound() {
return (
<>
<HeroPattern />
@@ -17,6 +17,4 @@ const NotFound = () => {
</div>
</>
);
};
export default NotFound;
}

View File

@@ -3,18 +3,18 @@
import { ThemeProvider, useTheme } from "next-themes";
import { useEffect } from "react";
const ThemeWatcher = () => {
function ThemeWatcher() {
let { resolvedTheme, setTheme } = useTheme();
useEffect(() => {
let media = window.matchMedia("(prefers-color-scheme: dark)");
const onMediaChange = () => {
function onMediaChange() {
let systemTheme = media.matches ? "dark" : "light";
if (resolvedTheme === systemTheme) {
setTheme("system");
}
};
}
onMediaChange();
media.addEventListener("change", onMediaChange);
@@ -25,13 +25,13 @@ const ThemeWatcher = () => {
}, [resolvedTheme, setTheme]);
return null;
};
}
export const Providers = ({ children }: { children: React.ReactNode }) => {
export function Providers({ children }: { children: React.ReactNode }) {
return (
<ThemeProvider attribute="class" disableTransitionOnChange>
<ThemeWatcher />
{children}
</ThemeProvider>
);
};
}

View File

@@ -17,12 +17,6 @@ Formbricks v2.0 comes with huge features such as Multi-Language Surveys and Adva
the upgrade. Follow the below steps thoroughly to upgrade your Formbricks instance to v2.0.
</Note>
and
<Note>
If you've used the Formbricks Enterprise Edition with a free beta license key, your instance will be downgraded to the Community Edition 2.0. You find all license details on the [license page.](/self-hosting/license/)
</Note>
### Steps to Migrate
This guide is for users who are self-hosting Formbricks using our one-click setup. If you are using a different setup, you might adjust the commands accordingly.

View File

@@ -33,7 +33,7 @@ const libraries = [
},
];
export const Libraries = () => {
export function Libraries() {
return (
<div className="my-16 xl:max-w-none">
<div className="not-prose mt-4 grid grid-cols-1 gap-x-6 gap-y-10 border-slate-900/5 sm:grid-cols-2 xl:max-w-none xl:grid-cols-3 dark:border-white/5">
@@ -57,4 +57,4 @@ export const Libraries = () => {
</div>
</div>
);
};
}

View File

@@ -1,7 +1,7 @@
import clsx from "clsx";
import Link from "next/link";
const ArrowIcon = (props: React.ComponentPropsWithoutRef<"svg">) => {
function ArrowIcon(props: React.ComponentPropsWithoutRef<"svg">) {
return (
<svg viewBox="0 0 20 20" fill="none" aria-hidden="true" {...props}>
<path
@@ -12,7 +12,7 @@ const ArrowIcon = (props: React.ComponentPropsWithoutRef<"svg">) => {
/>
</svg>
);
};
}
const variantStyles = {
primary:
@@ -34,7 +34,7 @@ type ButtonProps = {
| (React.ComponentPropsWithoutRef<"button"> & { href?: undefined })
);
export const Button = ({ variant = "primary", className, children, arrow, ...props }: ButtonProps) => {
export function Button({ variant = "primary", className, children, arrow, ...props }: ButtonProps) {
className = clsx(
"inline-flex gap-0.5 justify-center items-center overflow-hidden font-medium transition text-center",
variantStyles[variant],
@@ -74,4 +74,4 @@ export const Button = ({ variant = "primary", className, children, arrow, ...pro
{inner}
</Link>
);
};
}

View File

@@ -17,7 +17,7 @@ const languageNames: Record<string, string> = {
go: "Go",
};
const getPanelTitle = ({ title, language }: { title?: string; language?: string }) => {
function getPanelTitle({ title, language }: { title?: string; language?: string }) {
if (title) {
return title;
}
@@ -25,9 +25,9 @@ const getPanelTitle = ({ title, language }: { title?: string; language?: string
return languageNames[language];
}
return "Code";
};
}
const ClipboardIcon = (props: React.ComponentPropsWithoutRef<"svg">) => {
function ClipboardIcon(props: React.ComponentPropsWithoutRef<"svg">) {
return (
<svg viewBox="0 0 20 20" aria-hidden="true" {...props}>
<path
@@ -41,9 +41,9 @@ const ClipboardIcon = (props: React.ComponentPropsWithoutRef<"svg">) => {
/>
</svg>
);
};
}
const CopyButton = ({ code }: { code: string }) => {
function CopyButton({ code }: { code: string }) {
let [copyCount, setCopyCount] = useState(0);
let copied = copyCount > 0;
@@ -89,9 +89,9 @@ const CopyButton = ({ code }: { code: string }) => {
</span>
</button>
);
};
}
const CodePanelHeader = ({ tag, label }: { tag?: string; label?: string }) => {
function CodePanelHeader({ tag, label }: { tag?: string; label?: string }) {
if (!tag && !label) {
return null;
}
@@ -107,9 +107,9 @@ const CodePanelHeader = ({ tag, label }: { tag?: string; label?: string }) => {
{label && <span className="font-mono text-xs text-slate-400">{label}</span>}
</div>
);
};
}
const CodePanel = ({
function CodePanel({
children,
tag,
label,
@@ -119,7 +119,7 @@ const CodePanel = ({
tag?: string;
label?: string;
code?: string;
}) => {
}) {
let child = Children.only(children);
if (isValidElement(child)) {
@@ -141,9 +141,9 @@ const CodePanel = ({
</div>
</div>
);
};
}
const CodeGroupHeader = ({
function CodeGroupHeader({
title,
children,
selectedIndex,
@@ -151,7 +151,7 @@ const CodeGroupHeader = ({
title: string;
children: React.ReactNode;
selectedIndex: number;
}) => {
}) {
let hasTabs = Children.count(children) >= 1;
if (!title && !hasTabs) {
@@ -178,9 +178,9 @@ const CodeGroupHeader = ({
)}
</div>
);
};
}
const CodeGroupPanels = ({ children, ...props }: React.ComponentPropsWithoutRef<typeof CodePanel>) => {
function CodeGroupPanels({ children, ...props }: React.ComponentPropsWithoutRef<typeof CodePanel>) {
let hasTabs = Children.count(children) >= 1;
if (hasTabs) {
@@ -196,9 +196,9 @@ const CodeGroupPanels = ({ children, ...props }: React.ComponentPropsWithoutRef<
}
return <CodePanel {...props}>{children}</CodePanel>;
};
}
const usePreventLayoutShift = () => {
function usePreventLayoutShift() {
let positionRef = useRef<HTMLElement>(null);
let rafRef = useRef<number>();
@@ -227,7 +227,7 @@ const usePreventLayoutShift = () => {
});
},
};
};
}
const usePreferredLanguageStore = create<{
preferredLanguages: Array<string>;
@@ -243,7 +243,7 @@ const usePreferredLanguageStore = create<{
})),
}));
const useTabGroupProps = (availableLanguages: Array<string>) => {
function useTabGroupProps(availableLanguages: Array<string>) {
let { preferredLanguages, addPreferredLanguage } = usePreferredLanguageStore();
let [selectedIndex, setSelectedIndex] = useState(0);
let activeLanguage = [...availableLanguages].sort(
@@ -265,15 +265,15 @@ const useTabGroupProps = (availableLanguages: Array<string>) => {
preventLayoutShift(() => addPreferredLanguage(availableLanguages[newSelectedIndex]));
},
};
};
}
const CodeGroupContext = createContext(false);
export const CodeGroup = ({
export function CodeGroup({
children,
title,
...props
}: React.ComponentPropsWithoutRef<typeof CodeGroupPanels> & { title: string }) => {
}: React.ComponentPropsWithoutRef<typeof CodeGroupPanels> & { title: string }) {
let languages =
Children.map(children, (child) => getPanelTitle(isValidElement(child) ? child.props : {})) ?? [];
let tabGroupProps = useTabGroupProps(languages);
@@ -303,9 +303,9 @@ export const CodeGroup = ({
)}
</CodeGroupContext.Provider>
);
};
}
export const Code = ({ children, ...props }: React.ComponentPropsWithoutRef<"code">) => {
export function Code({ children, ...props }: React.ComponentPropsWithoutRef<"code">) {
let isGrouped = useContext(CodeGroupContext);
if (isGrouped) {
@@ -316,9 +316,9 @@ export const Code = ({ children, ...props }: React.ComponentPropsWithoutRef<"cod
}
return <code {...props}>{children}</code>;
};
}
export const Pre = ({ children, ...props }: React.ComponentPropsWithoutRef<typeof CodeGroup>) => {
export function Pre({ children, ...props }: React.ComponentPropsWithoutRef<typeof CodeGroup>) {
let isGrouped = useContext(CodeGroupContext);
if (isGrouped) {
@@ -326,4 +326,4 @@ export const Pre = ({ children, ...props }: React.ComponentPropsWithoutRef<typeo
}
return <CodeGroup {...props}>{children}</CodeGroup>;
};
}

View File

@@ -3,7 +3,7 @@
import { Transition } from "@headlessui/react";
import { Fragment, forwardRef, useState } from "react";
const CheckIcon = (props: React.ComponentPropsWithoutRef<"svg">) => {
function CheckIcon(props: React.ComponentPropsWithoutRef<"svg">) {
return (
<svg viewBox="0 0 20 20" aria-hidden="true" {...props}>
<circle cx="10" cy="10" r="10" strokeWidth="0" />
@@ -16,9 +16,9 @@ const CheckIcon = (props: React.ComponentPropsWithoutRef<"svg">) => {
/>
</svg>
);
};
}
const FeedbackButton = (props: Omit<React.ComponentPropsWithoutRef<"button">, "type" | "className">) => {
function FeedbackButton(props: Omit<React.ComponentPropsWithoutRef<"button">, "type" | "className">) {
return (
<button
type="submit"
@@ -26,12 +26,12 @@ const FeedbackButton = (props: Omit<React.ComponentPropsWithoutRef<"button">, "t
{...props}
/>
);
};
}
const FeedbackForm = forwardRef<
React.ElementRef<"form">,
Pick<React.ComponentPropsWithoutRef<"form">, "onSubmit">
>(({ onSubmit }, ref) => {
>(function FeedbackForm({ onSubmit }, ref) {
return (
<form
ref={ref}
@@ -47,9 +47,7 @@ const FeedbackForm = forwardRef<
);
});
FeedbackForm.displayName = "FeedbackForm";
const FeedbackThanks = forwardRef<React.ElementRef<"div">>((_props, ref) => {
const FeedbackThanks = forwardRef<React.ElementRef<"div">>(function FeedbackThanks(_props, ref) {
return (
<div ref={ref} className="absolute inset-0 flex justify-center md:justify-start">
<div className="flex items-center gap-3 rounded-full bg-teal-50/50 py-1 pl-1.5 pr-3 text-sm text-teal-900 ring-1 ring-inset ring-teal-500/20 dark:bg-teal-500/5 dark:text-teal-200 dark:ring-teal-500/30">
@@ -60,19 +58,17 @@ const FeedbackThanks = forwardRef<React.ElementRef<"div">>((_props, ref) => {
);
});
FeedbackThanks.displayName = "FeedbackThanks";
export const Feedback = () => {
export function Feedback() {
let [submitted, setSubmitted] = useState(false);
const onSubmit = (event: React.FormEvent<HTMLFormElement>) => {
function onSubmit(event: React.FormEvent<HTMLFormElement>) {
event.preventDefault();
// event.nativeEvent.submitter.dataset.response
// => "yes" or "no"
setSubmitted(true);
};
}
return (
<div className="relative h-8">
@@ -94,4 +90,4 @@ export const Feedback = () => {
</Transition>
</div>
);
};
}

View File

@@ -9,7 +9,7 @@ import { DiscordIcon } from "./icons/DiscordIcon";
import { GithubIcon } from "./icons/GithubIcon";
import { TwitterIcon } from "./icons/TwitterIcon";
const PageLink = ({
function PageLink({
label,
page,
previous = false,
@@ -17,7 +17,7 @@ const PageLink = ({
label: string;
page: { href: string; title: string };
previous?: boolean;
}) => {
}) {
return (
<>
<Button
@@ -36,9 +36,9 @@ const PageLink = ({
</Link>
</>
);
};
}
const PageNavigation = () => {
function PageNavigation() {
let pathname = usePathname();
let allPages = navigation.flatMap((group) => {
return group.links.flatMap((link) => {
@@ -72,9 +72,9 @@ const PageNavigation = () => {
)}
</div>
);
};
}
const SocialLink = ({
function SocialLink({
href,
icon: Icon,
children,
@@ -82,16 +82,16 @@ const SocialLink = ({
href: string;
icon: React.ComponentType<{ className?: string }>;
children: React.ReactNode;
}) => {
}) {
return (
<Link href={href} className="group">
<span className="sr-only">{children}</span>
<Icon className="h-5 w-5 fill-slate-700 transition group-hover:fill-slate-900 dark:group-hover:fill-slate-500" />
</Link>
);
};
}
const SmallPrint = () => {
function SmallPrint() {
const currentYear = new Date().getFullYear();
return (
@@ -112,13 +112,13 @@ const SmallPrint = () => {
</div>
</div>
);
};
}
export const Footer = () => {
export function Footer() {
return (
<footer className="mx-auto w-full max-w-2xl space-y-10 pb-16 lg:max-w-5xl">
<PageNavigation />
<SmallPrint />
</footer>
);
};
}

View File

@@ -1,6 +1,6 @@
import { useId } from "react";
export const GridPattern = ({
export function GridPattern({
width,
height,
x,
@@ -13,7 +13,7 @@ export const GridPattern = ({
x: string | number;
y: string | number;
squares: Array<[x: number, y: number]>;
}) => {
}) {
let patternId = useId();
return (
@@ -40,4 +40,4 @@ export const GridPattern = ({
)}
</svg>
);
};
}

View File

@@ -24,7 +24,7 @@ const guides = [
},
];
export const Guides = () => {
export function Guides() {
return (
<div className="my-16 xl:max-w-none">
<Heading level={2} id="guides">
@@ -45,4 +45,4 @@ export const Guides = () => {
</div>
</div>
);
};
}

View File

@@ -11,7 +11,7 @@ import { Button } from "./Button";
import { MobileNavigation, useIsInsideMobileNavigation, useMobileNavigationStore } from "./MobileNavigation";
import { ThemeToggle } from "./ThemeToggle";
const TopLevelNavItem = ({ href, children }: { href: string; children: React.ReactNode }) => {
function TopLevelNavItem({ href, children }: { href: string; children: React.ReactNode }) {
return (
<li>
<Link
@@ -21,9 +21,12 @@ const TopLevelNavItem = ({ href, children }: { href: string; children: React.Rea
</Link>
</li>
);
};
}
export const Header = forwardRef<React.ElementRef<"div">, { className?: string }>(({ className }, ref) => {
export const Header = forwardRef<React.ElementRef<"div">, { className?: string }>(function Header(
{ className },
ref
) {
let { isOpen: mobileNavIsOpen } = useMobileNavigationStore();
let isInsideMobileNavigation = useIsInsideMobileNavigation();
@@ -88,5 +91,3 @@ export const Header = forwardRef<React.ElementRef<"div">, { className?: string }
</motion.div>
);
});
Header.displayName = "Header";

View File

@@ -7,15 +7,15 @@ import { useInView } from "framer-motion";
import Link from "next/link";
import { useEffect, useRef } from "react";
const AnchorIcon = (props: React.ComponentPropsWithoutRef<"svg">) => {
function AnchorIcon(props: React.ComponentPropsWithoutRef<"svg">) {
return (
<svg viewBox="0 0 20 20" fill="none" strokeLinecap="round" aria-hidden="true" {...props}>
<path d="m6.5 11.5-.964-.964a3.535 3.535 0 1 1 5-5l.964.964m2 2 .964.964a3.536 3.536 0 0 1-5 5L8.5 13.5m0-5 3 3" />
</svg>
);
};
}
const Eyebrow = ({ tag, label }: { tag?: string; label?: string }) => {
function Eyebrow({ tag, label }: { tag?: string; label?: string }) {
if (!tag && !label) {
return null;
}
@@ -27,9 +27,9 @@ const Eyebrow = ({ tag, label }: { tag?: string; label?: string }) => {
{label && <span className="font-mono text-xs text-zinc-400">{label}</span>}
</div>
);
};
}
const Anchor = ({ id, inView, children }: { id: string; inView: boolean; children: React.ReactNode }) => {
function Anchor({ id, inView, children }: { id: string; inView: boolean; children: React.ReactNode }) {
return (
<Link href={`#${id}`} className="group text-inherit no-underline hover:text-inherit">
{inView && (
@@ -42,9 +42,9 @@ const Anchor = ({ id, inView, children }: { id: string; inView: boolean; childre
{children}
</Link>
);
};
}
export const Heading = <Level extends 2 | 3>({
export function Heading<Level extends 2 | 3>({
children,
tag,
label,
@@ -57,7 +57,7 @@ export const Heading = <Level extends 2 | 3>({
label?: string;
level?: Level;
anchor?: boolean;
}) => {
}) {
level = level ?? (2 as Level);
let Component = `h${level}` as "h2" | "h3";
let ref = useRef<HTMLHeadingElement>(null);
@@ -88,4 +88,4 @@ export const Heading = <Level extends 2 | 3>({
</Component>
</>
);
};
}

View File

@@ -1,6 +1,6 @@
import { GridPattern } from "./GridPattern";
export const HeroPattern = () => {
export function HeroPattern() {
return (
<div className="absolute inset-0 -z-10 mx-0 max-w-none overflow-hidden">
<div className="absolute left-1/2 top-0 ml-[-38rem] h-[25rem] w-[81.25rem] dark:[mask-image:linear-gradient(white,transparent)]">
@@ -28,4 +28,4 @@ export const HeroPattern = () => {
</div>
</div>
);
};
}

View File

@@ -10,13 +10,13 @@ import { Footer } from "./Footer";
import { Header } from "./Header";
import { type Section, SectionProvider } from "./SectionProvider";
export const Layout = ({
export function Layout({
children,
allSections,
}: {
children: React.ReactNode;
allSections: Record<string, Array<Section>>;
}) => {
}) {
let pathname = usePathname();
return (
@@ -42,4 +42,4 @@ export const Layout = ({
</div>
</SectionProvider>
);
};
}

View File

@@ -2,7 +2,7 @@ import logoDark from "@/images/logo/logo-dark.svg";
import logoLight from "@/images/logo/logo-light.svg";
import Image from "next/image";
export const Logo = ({ className }: { className?: string }) => {
export function Logo({ className }: { className?: string }) {
return (
<div>
<div className="block dark:hidden">
@@ -13,4 +13,4 @@ export const Logo = ({ className }: { className?: string }) => {
</div>
</div>
);
};
}

View File

@@ -1,6 +1,6 @@
import Image, { ImageProps } from "next/image";
import React from "react";
export const MdxImage = (props: ImageProps) => {
export function MdxImage(props: ImageProps) {
return <Image {...props} alt={props.alt} />;
};
}

View File

@@ -8,25 +8,25 @@ import { usePathname, useSearchParams } from "next/navigation";
import { Fragment, Suspense, createContext, useContext, useEffect, useRef } from "react";
import { create } from "zustand";
const MenuIcon = (props: React.ComponentPropsWithoutRef<"svg">) => {
function MenuIcon(props: React.ComponentPropsWithoutRef<"svg">) {
return (
<svg viewBox="0 0 10 9" fill="none" strokeLinecap="round" aria-hidden="true" {...props}>
<path d="M.5 1h9M.5 8h9M.5 4.5h9" />
</svg>
);
};
}
const XIcon = (props: React.ComponentPropsWithoutRef<"svg">) => {
function XIcon(props: React.ComponentPropsWithoutRef<"svg">) {
return (
<svg viewBox="0 0 10 9" fill="none" strokeLinecap="round" aria-hidden="true" {...props}>
<path d="m1.5 1 7 7M8.5 1l-7 7" />
</svg>
);
};
}
const IsInsideMobileNavigationContext = createContext(false);
const MobileNavigationDialog = ({ isOpen, close }: { isOpen: boolean; close: () => void }) => {
function MobileNavigationDialog({ isOpen, close }: { isOpen: boolean; close: () => void }) {
let pathname = usePathname();
let searchParams = useSearchParams();
let initialPathname = useRef(pathname).current;
@@ -38,7 +38,7 @@ const MobileNavigationDialog = ({ isOpen, close }: { isOpen: boolean; close: ()
}
}, [pathname, searchParams, close, initialPathname, initialSearchParams]);
const onClickDialog = (event: React.MouseEvent<HTMLDivElement>) => {
function onClickDialog(event: React.MouseEvent<HTMLDivElement>) {
if (!(event.target instanceof HTMLElement)) {
return;
}
@@ -51,7 +51,7 @@ const MobileNavigationDialog = ({ isOpen, close }: { isOpen: boolean; close: ()
) {
close();
}
};
}
return (
<Transition.Root show={isOpen} as={Fragment}>
@@ -97,11 +97,11 @@ const MobileNavigationDialog = ({ isOpen, close }: { isOpen: boolean; close: ()
</Dialog>
</Transition.Root>
);
};
}
export const useIsInsideMobileNavigation = () => {
export function useIsInsideMobileNavigation() {
return useContext(IsInsideMobileNavigationContext);
};
}
export const useMobileNavigationStore = create<{
isOpen: boolean;
@@ -115,7 +115,7 @@ export const useMobileNavigationStore = create<{
toggle: () => set((state) => ({ isOpen: !state.isOpen })),
}));
export const MobileNavigation = () => {
export function MobileNavigation() {
let isInsideMobileNavigation = useIsInsideMobileNavigation();
let { isOpen, toggle, close } = useMobileNavigationStore();
let ToggleIcon = isOpen ? XIcon : MenuIcon;
@@ -136,4 +136,4 @@ export const MobileNavigation = () => {
)}
</IsInsideMobileNavigationContext.Provider>
);
};
}

View File

@@ -35,12 +35,12 @@ export interface NavGroup {
links: Array<LinkWithHref | LinkWithChildren>;
}
const useInitialValue = <T,>(value: T, condition = true) => {
function useInitialValue<T>(value: T, condition = true) {
let initialValue = useRef(value).current;
return condition ? initialValue : value;
};
}
const NavLink = ({
function NavLink({
href,
children,
active = false,
@@ -50,7 +50,7 @@ const NavLink = ({
children: React.ReactNode;
active: boolean;
isAnchorLink?: boolean;
}) => {
}) {
return (
<Link
href={href}
@@ -65,9 +65,9 @@ const NavLink = ({
<span className="flex w-full truncate">{children}</span>
</Link>
);
};
}
const VisibleSectionHighlight = ({ group, pathname }: { group: NavGroup; pathname: string }) => {
function VisibleSectionHighlight({ group, pathname }: { group: NavGroup; pathname: string }) {
let [sections, visibleSections] = useInitialValue(
[useSectionStore((s) => s.sections), useSectionStore((s) => s.visibleSections)],
useIsInsideMobileNavigation()
@@ -99,9 +99,9 @@ const VisibleSectionHighlight = ({ group, pathname }: { group: NavGroup; pathnam
style={{ height, top }}
/>
);
};
}
const ActivePageMarker = ({ group, pathname }: { group: NavGroup; pathname: string }) => {
function ActivePageMarker({ group, pathname }: { group: NavGroup; pathname: string }) {
let itemHeight = remToPx(2);
let offset = remToPx(0.25);
let activePageIndex = group.links.findIndex(
@@ -122,9 +122,9 @@ const ActivePageMarker = ({ group, pathname }: { group: NavGroup; pathname: stri
style={{ top }}
/>
);
};
}
const NavigationGroup = ({
function NavigationGroup({
group,
className,
activeGroup,
@@ -138,7 +138,7 @@ const NavigationGroup = ({
setActiveGroup: (group: NavGroup | null) => void;
openGroups: string[];
setOpenGroups: (groups: string[]) => void;
}) => {
}) {
const isInsideMobileNavigation = useIsInsideMobileNavigation();
const pathname = usePathname();
const isActiveGroup = activeGroup?.title === group.title;
@@ -219,9 +219,9 @@ const NavigationGroup = ({
</div>
</li>
);
};
}
export const Navigation = (props: React.ComponentPropsWithoutRef<"nav">) => {
export function Navigation(props: React.ComponentPropsWithoutRef<"nav">) {
const [activeGroup, setActiveGroup] = useState<NavGroup | null>(navigation[0]);
const [openGroups, setOpenGroups] = useState<string[]>([]);
@@ -251,4 +251,4 @@ export const Navigation = (props: React.ComponentPropsWithoutRef<"nav">) => {
</ul>
</nav>
);
};
}

View File

@@ -1,13 +1,13 @@
import clsx from "clsx";
export const Prose = <T extends React.ElementType = "div">({
export function Prose<T extends React.ElementType = "div">({
as,
className,
...props
}: Omit<React.ComponentPropsWithoutRef<T>, "as" | "className"> & {
as?: T;
className?: string;
}) => {
}) {
let Component = as ?? "div";
return (
@@ -21,4 +21,4 @@ export const Prose = <T extends React.ElementType = "div">({
{...props}
/>
);
};
}

View File

@@ -72,22 +72,22 @@ const resources: Array<Resource> = [
},
];
const ResourceIcon = ({ icon: Icon }: { icon: Resource["icon"] }) => {
function ResourceIcon({ icon: Icon }: { icon: Resource["icon"] }) {
return (
<div className="dark:bg-white/7.5 flex h-7 w-7 items-center justify-center rounded-full bg-zinc-900/5 ring-1 ring-zinc-900/25 backdrop-blur-[2px] transition duration-300 group-hover:bg-white/50 group-hover:ring-zinc-900/25 dark:ring-white/15 dark:group-hover:bg-teal-300/10 dark:group-hover:ring-teal-400">
<Icon className="h-5 w-5 fill-zinc-700/10 stroke-zinc-700 transition-colors duration-300 group-hover:stroke-zinc-900 dark:fill-white/10 dark:stroke-zinc-400 dark:group-hover:fill-teal-300/10 dark:group-hover:stroke-teal-400" />
</div>
);
};
}
const ResourcePattern = ({
function ResourcePattern({
mouseX,
mouseY,
...gridProps
}: Resource["pattern"] & {
mouseX: MotionValue<number>;
mouseY: MotionValue<number>;
}) => {
}) {
let maskImage = useMotionTemplate`radial-gradient(180px at ${mouseX}px ${mouseY}px, white, transparent)`;
let style = { maskImage, WebkitMaskImage: maskImage };
@@ -119,17 +119,17 @@ const ResourcePattern = ({
</motion.div>
</div>
);
};
}
const Resource = ({ resource }: { resource: Resource }) => {
function Resource({ resource }: { resource: Resource }) {
let mouseX = useMotionValue(0);
let mouseY = useMotionValue(0);
const onMouseMove = ({ currentTarget, clientX, clientY }: React.MouseEvent<HTMLDivElement>) => {
function onMouseMove({ currentTarget, clientX, clientY }: React.MouseEvent<HTMLDivElement>) {
let { left, top } = currentTarget.getBoundingClientRect();
mouseX.set(clientX - left);
mouseY.set(clientY - top);
};
}
return (
<div
@@ -150,9 +150,9 @@ const Resource = ({ resource }: { resource: Resource }) => {
</div>
</div>
);
};
}
export const Resources = () => {
export function Resources() {
return (
<div className="my-16 xl:max-w-none">
<Heading level={2} id="resources">
@@ -165,4 +165,4 @@ export const Resources = () => {
</div>
</div>
);
};
}

View File

@@ -1,5 +1,5 @@
// ResponsiveVideo.js
export const ResponsiveVideo = ({ src, title }) => {
export function ResponsiveVideo({ src, title }) {
return (
<div className="relative w-full overflow-hidden pt-[56.25%]">
<iframe
@@ -12,4 +12,4 @@ export const ResponsiveVideo = ({ src, title }) => {
allowFullScreen></iframe>
</div>
);
};
}

View File

@@ -16,19 +16,19 @@ interface HitProps {
children: React.ReactNode;
}
const Hit = ({ hit, children }: HitProps) => {
function Hit({ hit, children }: HitProps) {
return <Link href={hit.url}>{children}</Link>;
};
}
const SearchIcon = (props: any) => {
function SearchIcon(props: any) {
return (
<svg aria-hidden="true" viewBox="0 0 20 20" {...props}>
<path d="M16.293 17.707a1 1 0 0 0 1.414-1.414l-1.414 1.414ZM9 14a5 5 0 0 1-5-5H2a7 7 0 0 0 7 7v-2ZM4 9a5 5 0 0 1 5-5V2a7 7 0 0 0-7 7h2Zm5-5a5 5 0 0 1 5 5h2a7 7 0 0 0-7-7v2Zm8.707 12.293-3.757-3.757-1.414 1.414 3.757 3.757 1.414-1.414ZM14 9a4.98 4.98 0 0 1-1.464 3.536l1.414 1.414A6.98 6.98 0 0 0 16 9h-2Zm-1.464 3.536A4.98 4.98 0 0 1 9 14v2a6.98 6.98 0 0 0 4.95-2.05l-1.414-1.414Z" />
</svg>
);
};
}
export const Search = () => {
export function Search() {
let { resolvedTheme } = useTheme();
let isLightMode = resolvedTheme === "light";
@@ -132,4 +132,4 @@ export const Search = () => {
)}
</>
);
};
}

View File

@@ -27,7 +27,7 @@ interface SectionState {
}) => void;
}
const createSectionStore = (sections: Array<Section>) => {
function createSectionStore(sections: Array<Section>) {
return createStore<SectionState>()((set) => ({
sections,
visibleSections: [],
@@ -49,14 +49,14 @@ const createSectionStore = (sections: Array<Section>) => {
};
}),
}));
};
}
const useVisibleSections = (sectionStore: StoreApi<SectionState>) => {
function useVisibleSections(sectionStore: StoreApi<SectionState>) {
let setVisibleSections = useStore(sectionStore, (s) => s.setVisibleSections);
let sections = useStore(sectionStore, (s) => s.sections);
useEffect(() => {
const checkVisibleSections = () => {
function checkVisibleSections() {
let { innerHeight, scrollY } = window;
let newVisibleSections: string[] = [];
@@ -90,7 +90,7 @@ const useVisibleSections = (sectionStore: StoreApi<SectionState>) => {
}
setVisibleSections(newVisibleSections);
};
}
let raf = window.requestAnimationFrame(() => checkVisibleSections());
window.addEventListener("scroll", checkVisibleSections, { passive: true });
@@ -102,19 +102,19 @@ const useVisibleSections = (sectionStore: StoreApi<SectionState>) => {
window.removeEventListener("resize", checkVisibleSections);
};
}, [setVisibleSections, sections]);
};
}
const SectionStoreContext = createContext<StoreApi<SectionState> | null>(null);
const useIsomorphicLayoutEffect = typeof window === "undefined" ? useEffect : useLayoutEffect;
export const SectionProvider = ({
export function SectionProvider({
sections,
children,
}: {
sections: Array<Section>;
children: React.ReactNode;
}) => {
}) {
let [sectionStore] = useState(() => createSectionStore(sections));
useVisibleSections(sectionStore);
@@ -124,9 +124,9 @@ export const SectionProvider = ({
}, [sectionStore, sections]);
return <SectionStoreContext.Provider value={sectionStore}>{children}</SectionStoreContext.Provider>;
};
}
export const useSectionStore = <T,>(selector: (state: SectionState) => T) => {
const store = useContext(SectionStoreContext);
export function useSectionStore<T>(selector: (state: SectionState) => T) {
let store = useContext(SectionStoreContext);
return useStore(store!, selector);
};
}

View File

@@ -39,7 +39,7 @@ const valueColorMap = {
DELETE: "rose",
} as Record<string, keyof typeof colorStyles>;
export const Tag = ({
export function Tag({
children,
variant = "medium",
color = valueColorMap[children] ?? "teal",
@@ -47,7 +47,7 @@ export const Tag = ({
children: keyof typeof valueColorMap & (string | {});
variant?: keyof typeof variantStyles;
color?: keyof typeof colorStyles;
}) => {
}) {
return (
<span
className={clsx(
@@ -58,4 +58,4 @@ export const Tag = ({
{children}
</span>
);
};
}

View File

@@ -1,6 +1,6 @@
import React from "react";
export const TellaVideo = ({ tellaVideoIdentifier }: { tellaVideoIdentifier: string }) => {
export function TellaVideo({ tellaVideoIdentifier }: { tellaVideoIdentifier: string }) {
return (
<div>
<iframe
@@ -15,4 +15,4 @@ export const TellaVideo = ({ tellaVideoIdentifier }: { tellaVideoIdentifier: str
title="Tella Video Help"></iframe>
</div>
);
};
}

View File

@@ -1,7 +1,7 @@
import { useTheme } from "next-themes";
import { useEffect, useState } from "react";
const SunIcon = (props: React.ComponentPropsWithoutRef<"svg">) => {
function SunIcon(props: React.ComponentPropsWithoutRef<"svg">) {
return (
<svg viewBox="0 0 20 20" fill="none" aria-hidden="true" {...props}>
<path d="M12.5 10a2.5 2.5 0 1 1-5 0 2.5 2.5 0 0 1 5 0Z" />
@@ -11,17 +11,17 @@ const SunIcon = (props: React.ComponentPropsWithoutRef<"svg">) => {
/>
</svg>
);
};
}
const MoonIcon = (props: React.ComponentPropsWithoutRef<"svg">) => {
function MoonIcon(props: React.ComponentPropsWithoutRef<"svg">) {
return (
<svg viewBox="0 0 20 20" fill="none" aria-hidden="true" {...props}>
<path d="M15.224 11.724a5.5 5.5 0 0 1-6.949-6.949 5.5 5.5 0 1 0 6.949 6.949Z" />
</svg>
);
};
}
export const ThemeToggle = () => {
export function ThemeToggle() {
let { resolvedTheme, setTheme } = useTheme();
let otherTheme = resolvedTheme === "dark" ? "light" : "dark";
let [mounted, setMounted] = useState(false);
@@ -40,4 +40,4 @@ export const ThemeToggle = () => {
<MoonIcon className="hidden h-5 w-5 stroke-white dark:block" />
</button>
);
};
}

View File

@@ -1,4 +1,4 @@
export const BellIcon = (props: React.ComponentPropsWithoutRef<"svg">) => {
export function BellIcon(props: React.ComponentPropsWithoutRef<"svg">) {
return (
<svg viewBox="0 0 20 20" aria-hidden="true" {...props}>
<path
@@ -14,4 +14,4 @@ export const BellIcon = (props: React.ComponentPropsWithoutRef<"svg">) => {
/>
</svg>
);
};
}

View File

@@ -1,4 +1,4 @@
export const BoltIcon = (props: React.ComponentPropsWithoutRef<"svg">) => {
export function BoltIcon(props: React.ComponentPropsWithoutRef<"svg">) {
return (
<svg viewBox="0 0 20 20" aria-hidden="true" {...props}>
<path
@@ -8,4 +8,4 @@ export const BoltIcon = (props: React.ComponentPropsWithoutRef<"svg">) => {
/>
</svg>
);
};
}

View File

@@ -1,4 +1,4 @@
export const BookIcon = (props: React.ComponentPropsWithoutRef<"svg">) => {
export function BookIcon(props: React.ComponentPropsWithoutRef<"svg">) {
return (
<svg viewBox="0 0 20 20" aria-hidden="true" {...props}>
<path
@@ -10,4 +10,4 @@ export const BookIcon = (props: React.ComponentPropsWithoutRef<"svg">) => {
<path strokeLinecap="round" strokeLinejoin="round" d="m17.5 2.5-7.5 3v12l7.5-3v-12Z" />
</svg>
);
};
}

View File

@@ -1,4 +1,4 @@
export const CalendarIcon = (props: React.ComponentPropsWithoutRef<"svg">) => {
export function CalendarIcon(props: React.ComponentPropsWithoutRef<"svg">) {
return (
<svg viewBox="0 0 20 20" aria-hidden="true" {...props}>
<path
@@ -15,4 +15,4 @@ export const CalendarIcon = (props: React.ComponentPropsWithoutRef<"svg">) => {
<path fill="none" strokeLinecap="round" strokeLinejoin="round" d="M5.5 5.5v-3M14.5 5.5v-3" />
</svg>
);
};
}

View File

@@ -1,4 +1,4 @@
export const CartIcon = (props: React.ComponentPropsWithoutRef<"svg">) => {
export function CartIcon(props: React.ComponentPropsWithoutRef<"svg">) {
return (
<svg viewBox="0 0 20 20" aria-hidden="true" {...props}>
<path
@@ -12,4 +12,4 @@ export const CartIcon = (props: React.ComponentPropsWithoutRef<"svg">) => {
/>
</svg>
);
};
}

View File

@@ -1,4 +1,4 @@
export const ChatBubbleIcon = (props: React.ComponentPropsWithoutRef<"svg">) => {
export function ChatBubbleIcon(props: React.ComponentPropsWithoutRef<"svg">) {
return (
<svg viewBox="0 0 20 20" aria-hidden="true" {...props}>
<path
@@ -9,4 +9,4 @@ export const ChatBubbleIcon = (props: React.ComponentPropsWithoutRef<"svg">) =>
<path fill="none" strokeLinecap="round" strokeLinejoin="round" d="M7.5 8.5h5M8.5 11.5h3" />
</svg>
);
};
}

View File

@@ -1,8 +1,8 @@
export const CheckIcon = (props: React.ComponentPropsWithoutRef<"svg">) => {
export function CheckIcon(props: React.ComponentPropsWithoutRef<"svg">) {
return (
<svg viewBox="0 0 20 20" aria-hidden="true" {...props}>
<path strokeLinecap="round" strokeLinejoin="round" d="M10 1.5a8.5 8.5 0 1 1 0 17 8.5 8.5 0 0 1 0-17Z" />
<path fill="none" strokeLinecap="round" strokeLinejoin="round" d="m7.5 10.5 2 2c1-3.5 3-5 3-5" />
</svg>
);
};
}

View File

@@ -1,4 +1,4 @@
export const ChevronRightLeftIcon = (props: React.ComponentPropsWithoutRef<"svg">) => {
export function ChevronRightLeftIcon(props: React.ComponentPropsWithoutRef<"svg">) {
return (
<svg viewBox="0 0 20 20" aria-hidden="true" {...props}>
<path
@@ -14,4 +14,4 @@ export const ChevronRightLeftIcon = (props: React.ComponentPropsWithoutRef<"svg"
/>
</svg>
);
};
}

View File

@@ -1,4 +1,4 @@
export const ClipboardIcon = (props: React.ComponentPropsWithoutRef<"svg">) => {
export function ClipboardIcon(props: React.ComponentPropsWithoutRef<"svg">) {
return (
<svg viewBox="0 0 20 20" aria-hidden="true" {...props}>
<path
@@ -14,4 +14,4 @@ export const ClipboardIcon = (props: React.ComponentPropsWithoutRef<"svg">) => {
/>
</svg>
);
};
}

View File

@@ -1,4 +1,4 @@
export const CogIcon = (props: React.ComponentPropsWithoutRef<"svg">) => {
export function CogIcon(props: React.ComponentPropsWithoutRef<"svg">) {
return (
<svg viewBox="0 0 20 20" aria-hidden="true" {...props}>
<path
@@ -16,4 +16,4 @@ export const CogIcon = (props: React.ComponentPropsWithoutRef<"svg">) => {
<circle cx="10" cy="10" r="2.5" fill="none" />
</svg>
);
};
}

View File

@@ -1,4 +1,4 @@
export const CopyIcon = (props: React.ComponentPropsWithoutRef<"svg">) => {
export function CopyIcon(props: React.ComponentPropsWithoutRef<"svg">) {
return (
<svg viewBox="0 0 20 20" aria-hidden="true" {...props}>
<path
@@ -14,4 +14,4 @@ export const CopyIcon = (props: React.ComponentPropsWithoutRef<"svg">) => {
/>
</svg>
);
};
}

View File

@@ -1,4 +1,4 @@
export const DocumentIcon = (props: React.ComponentPropsWithoutRef<"svg">) => {
export function DocumentIcon(props: React.ComponentPropsWithoutRef<"svg">) {
return (
<svg viewBox="0 0 20 20" aria-hidden="true" {...props}>
<path
@@ -9,4 +9,4 @@ export const DocumentIcon = (props: React.ComponentPropsWithoutRef<"svg">) => {
<path fill="none" strokeLinecap="round" strokeLinejoin="round" d="m11.5 2.5 5 5" />
</svg>
);
};
}

View File

@@ -1,4 +1,4 @@
export const EnvelopeIcon = (props: React.ComponentPropsWithoutRef<"svg">) => {
export function EnvelopeIcon(props: React.ComponentPropsWithoutRef<"svg">) {
return (
<svg viewBox="0 0 20 20" aria-hidden="true" {...props}>
<path
@@ -14,4 +14,4 @@ export const EnvelopeIcon = (props: React.ComponentPropsWithoutRef<"svg">) => {
/>
</svg>
);
};
}

View File

@@ -1,4 +1,4 @@
export const FaceSmileIcon = (props: React.ComponentPropsWithoutRef<"svg">) => {
export function FaceSmileIcon(props: React.ComponentPropsWithoutRef<"svg">) {
return (
<svg viewBox="0 0 20 20" aria-hidden="true" {...props}>
<path strokeLinecap="round" strokeLinejoin="round" d="M10 1.5a8.5 8.5 0 1 1 0 17 8.5 8.5 0 0 1 0-17Z" />
@@ -10,4 +10,4 @@ export const FaceSmileIcon = (props: React.ComponentPropsWithoutRef<"svg">) => {
/>
</svg>
);
};
}

View File

@@ -1,4 +1,4 @@
export const FolderIcon = (props: React.ComponentPropsWithoutRef<"svg">) => {
export function FolderIcon(props: React.ComponentPropsWithoutRef<"svg">) {
return (
<svg viewBox="0 0 20 20" aria-hidden="true" {...props}>
<path
@@ -16,4 +16,4 @@ export const FolderIcon = (props: React.ComponentPropsWithoutRef<"svg">) => {
/>
</svg>
);
};
}

View File

@@ -1,4 +1,4 @@
export const LinkIcon = (props: React.ComponentPropsWithoutRef<"svg">) => {
export function LinkIcon(props: React.ComponentPropsWithoutRef<"svg">) {
return (
<svg viewBox="0 0 20 20" aria-hidden="true" {...props}>
<path
@@ -9,4 +9,4 @@ export const LinkIcon = (props: React.ComponentPropsWithoutRef<"svg">) => {
/>
</svg>
);
};
}

View File

@@ -1,4 +1,4 @@
export const ListIcon = (props: React.ComponentPropsWithoutRef<"svg">) => {
export function ListIcon(props: React.ComponentPropsWithoutRef<"svg">) {
return (
<svg viewBox="0 0 20 20" aria-hidden="true" {...props}>
<path
@@ -9,4 +9,4 @@ export const ListIcon = (props: React.ComponentPropsWithoutRef<"svg">) => {
<path fill="none" strokeLinecap="round" strokeLinejoin="round" d="M6.5 6.5h7M6.5 13.5h7M6.5 10h7" />
</svg>
);
};
}

View File

@@ -1,4 +1,4 @@
export const MagnifyingGlassIcon = (props: React.ComponentPropsWithoutRef<"svg">) => {
export function MagnifyingGlassIcon(props: React.ComponentPropsWithoutRef<"svg">) {
return (
<svg viewBox="0 0 20 20" aria-hidden="true" {...props}>
<path strokeWidth="0" d="M2.5 8.5a6 6 0 1 1 12 0 6 6 0 0 1-12 0Z" />
@@ -10,4 +10,4 @@ export const MagnifyingGlassIcon = (props: React.ComponentPropsWithoutRef<"svg">
/>
</svg>
);
};
}

View File

@@ -1,4 +1,4 @@
export const MapPinIcon = (props: React.ComponentPropsWithoutRef<"svg">) => {
export function MapPinIcon(props: React.ComponentPropsWithoutRef<"svg">) {
return (
<svg viewBox="0 0 20 20" aria-hidden="true" {...props}>
<path
@@ -16,4 +16,4 @@ export const MapPinIcon = (props: React.ComponentPropsWithoutRef<"svg">) => {
<circle cx="10" cy="8" r="1.5" fill="none" />
</svg>
);
};
}

View File

@@ -1,4 +1,4 @@
export const PackageIcon = (props: React.ComponentPropsWithoutRef<"svg">) => {
export function PackageIcon(props: React.ComponentPropsWithoutRef<"svg">) {
return (
<svg viewBox="0 0 20 20" aria-hidden="true" {...props}>
<path strokeWidth="0" d="m10 9.5-7.5-4v9l7.5 4v-9ZM10 9.5l7.5-4v9l-7.5 4v-9Z" />
@@ -10,4 +10,4 @@ export const PackageIcon = (props: React.ComponentPropsWithoutRef<"svg">) => {
/>
</svg>
);
};
}

View File

@@ -1,4 +1,4 @@
export const PaperAirplaneIcon = (props: React.ComponentPropsWithoutRef<"svg">) => {
export function PaperAirplaneIcon(props: React.ComponentPropsWithoutRef<"svg">) {
return (
<svg viewBox="0 0 20 20" aria-hidden="true" {...props}>
<path
@@ -10,4 +10,4 @@ export const PaperAirplaneIcon = (props: React.ComponentPropsWithoutRef<"svg">)
<path strokeLinecap="round" strokeLinejoin="round" d="M11 19L8 12L17 3L11 19Z" />
</svg>
);
};
}

View File

@@ -1,4 +1,4 @@
export const PaperClipIcon = (props: React.ComponentPropsWithoutRef<"svg">) => {
export function PaperClipIcon(props: React.ComponentPropsWithoutRef<"svg">) {
return (
<svg viewBox="0 0 20 20" aria-hidden="true" {...props}>
<path
@@ -9,4 +9,4 @@ export const PaperClipIcon = (props: React.ComponentPropsWithoutRef<"svg">) => {
/>
</svg>
);
};
}

View File

@@ -1,4 +1,4 @@
export const ShapesIcon = (props: React.ComponentPropsWithoutRef<"svg">) => {
export function ShapesIcon(props: React.ComponentPropsWithoutRef<"svg">) {
return (
<svg viewBox="0 0 20 20" aria-hidden="true" {...props}>
<path
@@ -14,4 +14,4 @@ export const ShapesIcon = (props: React.ComponentPropsWithoutRef<"svg">) => {
/>
</svg>
);
};
}

View File

@@ -1,4 +1,4 @@
export const ShirtIcon = (props: React.ComponentPropsWithoutRef<"svg">) => {
export function ShirtIcon(props: React.ComponentPropsWithoutRef<"svg">) {
return (
<svg viewBox="0 0 20 20" aria-hidden="true" {...props}>
<path
@@ -8,4 +8,4 @@ export const ShirtIcon = (props: React.ComponentPropsWithoutRef<"svg">) => {
/>
</svg>
);
};
}

View File

@@ -1,4 +1,4 @@
export const SquaresPlusIcon = (props: React.ComponentPropsWithoutRef<"svg">) => {
export function SquaresPlusIcon(props: React.ComponentPropsWithoutRef<"svg">) {
return (
<svg viewBox="0 0 20 20" aria-hidden="true" {...props}>
<path
@@ -9,4 +9,4 @@ export const SquaresPlusIcon = (props: React.ComponentPropsWithoutRef<"svg">) =>
<path fill="none" strokeLinecap="round" strokeLinejoin="round" d="M14.5 11.5v6M17.5 14.5h-6" />
</svg>
);
};
}

View File

@@ -1,4 +1,4 @@
export const TagIcon = (props: React.ComponentPropsWithoutRef<"svg">) => {
export function TagIcon(props: React.ComponentPropsWithoutRef<"svg">) {
return (
<svg viewBox="0 0 20 20" aria-hidden="true" {...props}>
<path
@@ -16,4 +16,4 @@ export const TagIcon = (props: React.ComponentPropsWithoutRef<"svg">) => {
<circle cx="7" cy="7" r="1.5" fill="none" />
</svg>
);
};
}

View File

@@ -1,4 +1,4 @@
export const UserIcon = (props: React.ComponentPropsWithoutRef<"svg">) => {
export function UserIcon(props: React.ComponentPropsWithoutRef<"svg">) {
return (
<svg viewBox="0 0 20 20" aria-hidden="true" {...props}>
<path
@@ -21,4 +21,4 @@ export const UserIcon = (props: React.ComponentPropsWithoutRef<"svg">) => {
/>
</svg>
);
};
}

View File

@@ -1,4 +1,4 @@
export const UsersIcon = (props: React.ComponentPropsWithoutRef<"svg">) => {
export function UsersIcon(props: React.ComponentPropsWithoutRef<"svg">) {
return (
<svg viewBox="0 0 20 20" aria-hidden="true" {...props}>
<path
@@ -21,4 +21,4 @@ export const UsersIcon = (props: React.ComponentPropsWithoutRef<"svg">) => {
<path strokeLinecap="round" strokeLinejoin="round" d="M13 2a2.5 2.5 0 1 1 0 5 2.5 2.5 0 0 1 0-5Z" />
</svg>
);
};
}

View File

@@ -8,7 +8,7 @@ export const a = Link;
export { Button } from "@/components/Button";
export { CodeGroup, Code as code, Pre as pre } from "@/components/Code";
export const wrapper = ({ children }: { children: React.ReactNode }) => {
export function wrapper({ children }: { children: React.ReactNode }) {
return (
<article className="flex h-full flex-col pb-10 pt-16">
<Prose className="flex-auto font-normal">{children}</Prose>
@@ -17,13 +17,13 @@ export const wrapper = ({ children }: { children: React.ReactNode }) => {
</footer>
</article>
);
};
}
export const h2 = (props: Omit<React.ComponentPropsWithoutRef<typeof Heading>, "level">) => {
export const h2 = function H2(props: Omit<React.ComponentPropsWithoutRef<typeof Heading>, "level">) {
return <Heading level={2} {...props} />;
};
const InfoIcon = (props: React.ComponentPropsWithoutRef<"svg">) => {
function InfoIcon(props: React.ComponentPropsWithoutRef<"svg">) {
return (
<svg viewBox="0 0 16 16" aria-hidden="true" {...props}>
<circle cx="8" cy="8" r="8" strokeWidth="0" />
@@ -37,34 +37,34 @@ const InfoIcon = (props: React.ComponentPropsWithoutRef<"svg">) => {
<circle cx="8" cy="4" r=".5" fill="none" />
</svg>
);
};
}
export const Note = ({ children }: { children: React.ReactNode }) => {
export function Note({ children }: { children: React.ReactNode }) {
return (
<div className="my-6 flex gap-2.5 rounded-2xl border border-teal-500/20 bg-teal-50/50 p-4 leading-6 text-teal-900 dark:border-teal-500/30 dark:bg-teal-500/5 dark:text-teal-200 dark:[--tw-prose-links-hover:theme(colors.teal.300)] dark:[--tw-prose-links:theme(colors.white)]">
<InfoIcon className="mt-1 h-4 w-4 flex-none fill-teal-500 stroke-white dark:fill-teal-200/20 dark:stroke-teal-200" />
<div className="[&>:first-child]:mt-0 [&>:last-child]:mb-0">{children}</div>
</div>
);
};
}
export const Row = ({ children }: { children: React.ReactNode }) => {
export function Row({ children }: { children: React.ReactNode }) {
return (
<div className="grid grid-cols-1 items-start gap-x-16 gap-y-10 xl:max-w-none xl:grid-cols-2">
{children}
</div>
);
};
}
export const Col = ({ children, sticky = false }: { children: React.ReactNode; sticky?: boolean }) => {
export function Col({ children, sticky = false }: { children: React.ReactNode; sticky?: boolean }) {
return (
<div className={clsx("[&>:first-child]:mt-0 [&>:last-child]:mb-0", sticky && "xl:sticky xl:top-24")}>
{children}
</div>
);
};
}
export const Properties = ({ children }: { children: React.ReactNode }) => {
export function Properties({ children }: { children: React.ReactNode }) {
return (
<div className="my-6">
<ul
@@ -74,9 +74,9 @@ export const Properties = ({ children }: { children: React.ReactNode }) => {
</ul>
</div>
);
};
}
export const Property = ({
export function Property({
name,
children,
type,
@@ -84,7 +84,7 @@ export const Property = ({
name: string;
children: React.ReactNode;
type?: string;
}) => {
}) {
return (
<li className="m-0 px-0 py-4 first:pt-0 last:pb-0">
<dl className="m-0 flex flex-wrap items-center gap-x-3 gap-y-2">
@@ -103,4 +103,4 @@ export const Property = ({
</dl>
</li>
);
};
}

View File

@@ -1,8 +1,8 @@
export const remToPx = (remValue: number) => {
export function remToPx(remValue: number) {
let rootFontSize =
typeof window === "undefined"
? 16
: parseFloat(window.getComputedStyle(document.documentElement).fontSize);
return remValue * rootFontSize;
};
}

View File

@@ -1,9 +1,9 @@
import * as mdxComponents from "@/components/mdx";
import { type MDXComponents } from "mdx/types";
export const useMDXComponents = (components: MDXComponents) => {
export function useMDXComponents(components: MDXComponents) {
return {
...components,
...mdxComponents,
};
};
}

View File

@@ -1,35 +1,42 @@
import { slugifyWithCounter } from "@sindresorhus/slugify";
import * as acorn from "acorn";
import { toString } from "mdast-util-to-string";
import { mdxAnnotations } from "mdx-annotations";
import { getHighlighter, renderToHtml } from "shiki";
import { visit } from "unist-util-visit";
import { slugifyWithCounter } from '@sindresorhus/slugify'
import * as acorn from 'acorn'
import { toString } from 'mdast-util-to-string'
import { mdxAnnotations } from 'mdx-annotations'
import { getHighlighter, renderToHtml } from 'shiki'
import { visit } from 'unist-util-visit'
const rehypeParseCodeBlocks = () => {
function rehypeParseCodeBlocks() {
return (tree) => {
visit(tree, "element", (node, _nodeIndex, parentNode) => {
if (node.tagName === "code" && node.properties.className) {
parentNode.properties.language = node.properties.className[0]?.replace(/^language-/, "");
visit(tree, 'element', (node, _nodeIndex, parentNode) => {
if (node.tagName === 'code' && node.properties.className) {
parentNode.properties.language = node.properties.className[0]?.replace(
/^language-/,
'',
)
}
});
};
};
})
}
}
let highlighter;
let highlighter
const rehypeShiki = () => {
function rehypeShiki() {
return async (tree) => {
highlighter = highlighter ?? (await getHighlighter({ theme: "css-variables" }));
highlighter =
highlighter ?? (await getHighlighter({ theme: 'css-variables' }))
visit(tree, "element", (node) => {
if (node.tagName === "pre" && node.children[0]?.tagName === "code") {
let codeNode = node.children[0];
let textNode = codeNode.children[0];
visit(tree, 'element', (node) => {
if (node.tagName === 'pre' && node.children[0]?.tagName === 'code') {
let codeNode = node.children[0]
let textNode = codeNode.children[0]
node.properties.code = textNode.value;
node.properties.code = textNode.value
if (node.properties.language) {
let tokens = highlighter.codeToThemedTokens(textNode.value, node.properties.language);
let tokens = highlighter.codeToThemedTokens(
textNode.value,
node.properties.language,
)
textNode.value = renderToHtml(tokens, {
elements: {
@@ -37,68 +44,71 @@ const rehypeShiki = () => {
code: ({ children }) => children,
line: ({ children }) => `<span>${children}</span>`,
},
});
})
}
}
});
};
};
})
}
}
const rehypeSlugify = () => {
function rehypeSlugify() {
return (tree) => {
let slugify = slugifyWithCounter();
visit(tree, "element", (node) => {
if (node.tagName === "h2" && !node.properties.id) {
node.properties.id = slugify(toString(node));
let slugify = slugifyWithCounter()
visit(tree, 'element', (node) => {
if (node.tagName === 'h2' && !node.properties.id) {
node.properties.id = slugify(toString(node))
}
});
};
};
})
}
}
const rehypeAddMDXExports = (getExports) => {
function rehypeAddMDXExports(getExports) {
return (tree) => {
let exports = Object.entries(getExports(tree));
let exports = Object.entries(getExports(tree))
for (let [name, value] of exports) {
for (let node of tree.children) {
if (node.type === "mdxjsEsm" && new RegExp(`export\\s+const\\s+${name}\\s*=`).test(node.value)) {
return;
if (
node.type === 'mdxjsEsm' &&
new RegExp(`export\\s+const\\s+${name}\\s*=`).test(node.value)
) {
return
}
}
let exportStr = `export const ${name} = ${value}`;
let exportStr = `export const ${name} = ${value}`
tree.children.push({
type: "mdxjsEsm",
type: 'mdxjsEsm',
value: exportStr,
data: {
estree: acorn.parse(exportStr, {
sourceType: "module",
ecmaVersion: "latest",
sourceType: 'module',
ecmaVersion: 'latest',
}),
},
});
})
}
};
};
}
}
const getSections = (node) => {
let sections = [];
function getSections(node) {
let sections = []
for (let child of node.children ?? []) {
if (child.type === "element" && child.tagName === "h2") {
if (child.type === 'element' && child.tagName === 'h2') {
sections.push(`{
title: ${JSON.stringify(toString(child))},
id: ${JSON.stringify(child.properties.id)},
...${child.properties.annotation}
}`);
}`)
} else if (child.children) {
sections.push(...getSections(child));
sections.push(...getSections(child))
}
}
return sections;
};
return sections
}
export const rehypePlugins = [
mdxAnnotations.rehype,
@@ -111,4 +121,4 @@ export const rehypePlugins = [
sections: `[${getSections(tree).join()}]`,
}),
],
];
]

View File

@@ -1,36 +1,51 @@
import { slugifyWithCounter } from "@sindresorhus/slugify";
import glob from "fast-glob";
import * as fs from "fs";
import { toString } from "mdast-util-to-string";
import * as path from "path";
import { remark } from "remark";
import remarkMdx from "remark-mdx";
import { createLoader } from "simple-functional-loader";
import { filter } from "unist-util-filter";
import { SKIP, visit } from "unist-util-visit";
import * as url from "url";
import { slugifyWithCounter } from '@sindresorhus/slugify'
import glob from 'fast-glob'
import * as fs from 'fs'
import { toString } from 'mdast-util-to-string'
import * as path from 'path'
import { remark } from 'remark'
import remarkMdx from 'remark-mdx'
import { createLoader } from 'simple-functional-loader'
import { filter } from 'unist-util-filter'
import { SKIP, visit } from 'unist-util-visit'
import * as url from 'url'
const extractSections = () => {
const __filename = url.fileURLToPath(import.meta.url)
const processor = remark().use(remarkMdx).use(extractSections)
const slugify = slugifyWithCounter()
function isObjectExpression(node) {
return (
node.type === 'mdxTextExpression' &&
node.data?.estree?.body?.[0]?.expression?.type === 'ObjectExpression'
)
}
function excludeObjectExpressions(tree) {
return filter(tree, (node) => !isObjectExpression(node))
}
function extractSections() {
return (tree, { sections }) => {
slugify.reset();
slugify.reset()
visit(tree, (node) => {
if (node.type === "heading" || node.type === "paragraph") {
let content = toString(excludeObjectExpressions(node));
if (node.type === "heading" && node.depth <= 2) {
let hash = node.depth === 1 ? null : slugify(content);
sections.push([content, hash, []]);
if (node.type === 'heading' || node.type === 'paragraph') {
let content = toString(excludeObjectExpressions(node))
if (node.type === 'heading' && node.depth <= 2) {
let hash = node.depth === 1 ? null : slugify(content)
sections.push([content, hash, []])
} else {
sections.at(-1)?.[2].push(content);
sections.at(-1)?.[2].push(content)
}
return SKIP;
return SKIP
}
});
};
};
})
}
}
export const Search = (nextConfig = {}) => {
let cache = new Map();
export default function Search(nextConfig = {}) {
let cache = new Map()
return Object.assign({}, nextConfig, {
webpack(config, options) {
@@ -38,26 +53,26 @@ export const Search = (nextConfig = {}) => {
test: __filename,
use: [
createLoader(function () {
let appDir = path.resolve("./src/app");
this.addContextDependency(appDir);
let appDir = path.resolve('./src/app')
this.addContextDependency(appDir)
let files = glob.sync("**/*.mdx", { cwd: appDir });
let files = glob.sync('**/*.mdx', { cwd: appDir })
let data = files.map((file) => {
let url = "/" + file.replace(/(^|\/)page\.mdx$/, "");
let mdx = fs.readFileSync(path.join(appDir, file), "utf8");
let url = '/' + file.replace(/(^|\/)page\.mdx$/, '')
let mdx = fs.readFileSync(path.join(appDir, file), 'utf8')
let sections = [];
let sections = []
if (cache.get(file)?.[0] === mdx) {
sections = cache.get(file)[1];
sections = cache.get(file)[1]
} else {
let vfile = { value: mdx, sections };
processor.runSync(processor.parse(vfile), vfile);
cache.set(file, [mdx, sections]);
let vfile = { value: mdx, sections }
processor.runSync(processor.parse(vfile), vfile)
cache.set(file, [mdx, sections])
}
return { url, sections };
});
return { url, sections }
})
// When this file is imported within the application
// the following module is loaded:
@@ -91,7 +106,7 @@ export const Search = (nextConfig = {}) => {
}
}
export const search = (query, options = {}) => {
export function search(query, options = {}) {
let result = sectionIndex.search(query, {
...options,
enrich: true,
@@ -105,30 +120,16 @@ export const Search = (nextConfig = {}) => {
pageTitle: item.doc.pageTitle,
}))
}
`;
`
}),
],
});
})
if (typeof nextConfig.webpack === "function") {
return nextConfig.webpack(config, options);
if (typeof nextConfig.webpack === 'function') {
return nextConfig.webpack(config, options)
}
return config;
return config
},
});
};
const __filename = url.fileURLToPath(import.meta.url);
const processor = remark().use(remarkMdx).use(extractSections);
const slugify = slugifyWithCounter();
const isObjectExpression = (node) => {
return (
node.type === "mdxTextExpression" && node.data?.estree?.body?.[0]?.expression?.type === "ObjectExpression"
);
};
const excludeObjectExpressions = (tree) => {
return filter(tree, (node) => !isObjectExpression(node));
};
})
}

View File

@@ -3,7 +3,7 @@ import nextMDX from "@next/mdx";
import { recmaPlugins } from "./mdx/recma.mjs";
import { rehypePlugins } from "./mdx/rehype.mjs";
import { remarkPlugins } from "./mdx/remark.mjs";
import { Search as withSearch } from "./mdx/search.mjs";
import withSearch from "./mdx/search.mjs";
const withMDX = nextMDX({
options: {

View File

@@ -1,12 +1,10 @@
import { MetadataRoute } from "next";
const robots = (): MetadataRoute.Robots => {
export default function robots(): MetadataRoute.Robots {
return {
rules: {
userAgent: "*",
allow: "/",
},
};
};
export default robots;
}

View File

@@ -7,5 +7,5 @@ declare module "@/mdx/search.mjs" {
pageTitle?: string;
};
export const search: (query: string, options?: SearchOptions) => Array<Result>;
export function search(query: string, options?: SearchOptions): Array<Result>;
}

View File

@@ -1,6 +1,6 @@
import { type PluginUtils } from "tailwindcss/types/config";
const typographyStyles = ({ theme }: PluginUtils) => {
export default function typographyStyles({ theme }: PluginUtils) {
return {
DEFAULT: {
css: {
@@ -367,6 +367,4 @@ const typographyStyles = ({ theme }: PluginUtils) => {
},
},
};
};
export default typographyStyles;
}

View File

@@ -5,11 +5,10 @@ import { dirname, join } from "path";
* This function is used to resolve the absolute path of a package.
* It is needed in projects that use Yarn PnP or are set up within a monorepo.
*/
const getAbsolutePath = (value: string): any => {
function getAbsolutePath(value: string): any {
return dirname(require.resolve(join(value, "package.json")));
};
export const config: StorybookConfig = {
}
const config: StorybookConfig = {
stories: ["../../../packages/ui/**/stories.@(js|jsx|mjs|ts|tsx)"],
addons: [
getAbsolutePath("@storybook/addon-links"),
@@ -25,3 +24,4 @@ export const config: StorybookConfig = {
autodocs: "tag",
},
};
export default config;

View File

@@ -2,7 +2,7 @@ import type { Preview } from "@storybook/react";
import "../src/index.css";
export const preview: Preview = {
const preview: Preview = {
parameters: {
actions: { argTypesRegex: "^on[A-Z].*" },
controls: {
@@ -13,3 +13,5 @@ export const preview: Preview = {
},
},
};
export default preview;

View File

@@ -2,7 +2,7 @@ import { useState } from "react";
import "./App.css";
export const App = () => {
function App() {
const [count, setCount] = useState(0);
return (
@@ -23,4 +23,6 @@ export const App = () => {
<p className="read-the-docs">Click on the Vite and React logos to learn more</p>
</>
);
};
}
export default App;

View File

@@ -1,5 +1,5 @@
import { FormbricksClient } from "@/app/(app)/components/FormbricksClient";
import { PosthogIdentify } from "@/app/(app)/environments/[environmentId]/components/PosthogIdentify";
import FormbricksClient from "@/app/(app)/components/FormbricksClient";
import PosthogIdentify from "@/app/(app)/environments/[environmentId]/components/PosthogIdentify";
import { ResponseFilterProvider } from "@/app/(app)/environments/[environmentId]/components/ResponseFilterContext";
import { getServerSession } from "next-auth";
import { redirect } from "next/navigation";
@@ -10,9 +10,9 @@ import { getEnvironment } from "@formbricks/lib/environment/service";
import { getTeamByEnvironmentId } from "@formbricks/lib/team/service";
import { AuthorizationError } from "@formbricks/types/errors";
import { DevEnvironmentBanner } from "@formbricks/ui/DevEnvironmentBanner";
import { ToasterClient } from "@formbricks/ui/ToasterClient";
import ToasterClient from "@formbricks/ui/ToasterClient";
const EnvLayout = async ({ children, params }) => {
export default async function EnvLayout({ children, params }) {
const session = await getServerSession(authOptions);
if (!session || !session.user) {
return redirect(`/auth/login`);
@@ -54,6 +54,4 @@ const EnvLayout = async ({ children, params }) => {
</ResponseFilterProvider>
</>
);
};
export default EnvLayout;
}

View File

@@ -30,11 +30,11 @@ import { TProduct } from "@formbricks/types/product";
import { TBaseFilters, TSegmentUpdateInput, ZSegmentFilters } from "@formbricks/types/segment";
import { TSurvey } from "@formbricks/types/surveys";
export const surveyMutateAction = async (survey: TSurvey): Promise<TSurvey> => {
export async function surveyMutateAction(survey: TSurvey): Promise<TSurvey> {
return await updateSurvey(survey);
};
}
export const updateSurveyAction = async (survey: TSurvey): Promise<TSurvey> => {
export async function updateSurveyAction(survey: TSurvey): Promise<TSurvey> {
const session = await getServerSession(authOptions);
if (!session) throw new AuthorizationError("Not authorized");
@@ -45,7 +45,7 @@ export const updateSurveyAction = async (survey: TSurvey): Promise<TSurvey> => {
if (!hasCreateOrUpdateAccess) throw new AuthorizationError("Not authorized");
return await updateSurvey(survey);
};
}
export const deleteSurveyAction = async (surveyId: string) => {
const session = await getServerSession(authOptions);
@@ -190,7 +190,7 @@ export const resetBasicSegmentFiltersAction = async (surveyId: string) => {
return await resetSegmentInSurvey(surveyId);
};
export const getImagesFromUnsplashAction = async (searchQuery: string, page: number = 1) => {
export async function getImagesFromUnsplashAction(searchQuery: string, page: number = 1) {
if (!UNSPLASH_ACCESS_KEY) {
throw new Error("Unsplash access key is not set");
}
@@ -231,9 +231,9 @@ export const getImagesFromUnsplashAction = async (searchQuery: string, page: num
} catch (error) {
throw new Error("Error getting images from Unsplash");
}
};
}
export const triggerDownloadUnsplashImageAction = async (downloadUrl: string) => {
export async function triggerDownloadUnsplashImageAction(downloadUrl: string) {
try {
const response = await fetch(`${downloadUrl}/?client_id=${UNSPLASH_ACCESS_KEY}`, {
method: "GET",
@@ -249,9 +249,9 @@ export const triggerDownloadUnsplashImageAction = async (downloadUrl: string) =>
} catch (error) {
throw new Error("Error downloading image from Unsplash");
}
};
}
export const createActionClassAction = async (action: TActionClassInput) => {
export async function createActionClassAction(action: TActionClassInput) {
const session = await getServerSession(authOptions);
if (!session) throw new AuthorizationError("Not authorized");
@@ -259,4 +259,4 @@ export const createActionClassAction = async (action: TActionClassInput) => {
if (!isAuthorized) throw new AuthorizationError("Not authorized");
return await createActionClass(action.environmentId, action);
};
}

View File

@@ -14,7 +14,7 @@ interface AddQuestionButtonProps {
product: TProduct;
}
export const AddQuestionButton = ({ addQuestion, product }: AddQuestionButtonProps) => {
export default function AddQuestionButton({ addQuestion, product }: AddQuestionButtonProps) {
const [open, setOpen] = useState(false);
return (
@@ -59,4 +59,4 @@ export const AddQuestionButton = ({ addQuestion, product }: AddQuestionButtonPro
</Collapsible.CollapsibleContent>
</Collapsible.Root>
);
};
}

View File

@@ -1,7 +1,7 @@
import { TSurvey, TSurveyQuestion } from "@formbricks/types/surveys";
import { LogicEditor } from "./LogicEditor";
import { UpdateQuestionId } from "./UpdateQuestionId";
import LogicEditor from "./LogicEditor";
import UpdateQuestionId from "./UpdateQuestionId";
interface AdvancedSettingsProps {
question: TSurveyQuestion;

Some files were not shown because too many files have changed in this diff Show More