Deleted a ton of old components, started tidying things up
This commit is contained in:
@@ -1,5 +1,26 @@
|
||||
import type { StorybookConfig } from "@storybook/react-webpack5";
|
||||
import path from "path";
|
||||
|
||||
const root = path.resolve(__dirname, "../app/");
|
||||
console.log("storybook root", root);
|
||||
|
||||
const config: StorybookConfig = {
|
||||
webpackFinal: async (config) => {
|
||||
return {
|
||||
...config,
|
||||
resolve: {
|
||||
...config.resolve,
|
||||
alias: {
|
||||
...(config.resolve?.alias ?? {}),
|
||||
"~/": root,
|
||||
},
|
||||
extensions: [
|
||||
...(config.resolve?.extensions ?? []),
|
||||
...[".ts", ".tsx", ".js", ".jsx", ".mdx"],
|
||||
],
|
||||
},
|
||||
};
|
||||
},
|
||||
stories: [
|
||||
"../app/**/stories/*.mdx",
|
||||
"../app/**/stories/*.stories.@(js|jsx|ts|tsx)",
|
||||
@@ -26,5 +47,6 @@ const config: StorybookConfig = {
|
||||
docs: {
|
||||
autodocs: "tag",
|
||||
},
|
||||
staticDirs: [path.resolve("public"), path.resolve("app/styles")],
|
||||
};
|
||||
export default config;
|
||||
|
||||
@@ -10,7 +10,7 @@ import type { TemplateListItem } from "~/presenters/templateListPresenter.server
|
||||
import { ApiLogoIcon } from "./code/ApiLogoIcon";
|
||||
import { Panel } from "./layout/Panel";
|
||||
import { Body } from "./primitives/text/Body";
|
||||
import { Header1, Header3 } from "./primitives/text/Headers";
|
||||
import { Header1, Header3 } from "./primitives/Headers";
|
||||
|
||||
export function LoginPromoPanel({ template }: { template?: TemplateListItem }) {
|
||||
return (
|
||||
|
||||
@@ -1,59 +0,0 @@
|
||||
type Props = Omit<
|
||||
React.DetailedHTMLProps<
|
||||
React.ImgHTMLAttributes<HTMLImageElement>,
|
||||
HTMLImageElement
|
||||
>,
|
||||
"src" | "alt"
|
||||
> & {
|
||||
integration?: { icon: string; name: string };
|
||||
size?: Size;
|
||||
};
|
||||
|
||||
type Size =
|
||||
| "extra-small"
|
||||
| "small"
|
||||
| "regular"
|
||||
| "large"
|
||||
| "extra-large"
|
||||
| "custom";
|
||||
|
||||
export function ApiLogoIcon({
|
||||
className,
|
||||
integration,
|
||||
size = "extra-large",
|
||||
...props
|
||||
}: Props) {
|
||||
if (!integration) {
|
||||
return null;
|
||||
}
|
||||
return (
|
||||
<img
|
||||
className={`
|
||||
rounded bg-slate-850
|
||||
${getSizeClassName(size)}
|
||||
${className}
|
||||
`}
|
||||
src={integration.icon}
|
||||
alt={integration.name}
|
||||
{...props}
|
||||
/>
|
||||
);
|
||||
}
|
||||
|
||||
function getSizeClassName(size: Size) {
|
||||
switch (size) {
|
||||
case "extra-small":
|
||||
return "h-6 w-6 p-2";
|
||||
case "small":
|
||||
return "h-8 w-8 p-2";
|
||||
case "large":
|
||||
return "h-16 w-16 p-2";
|
||||
case "extra-large":
|
||||
return "h-20 w-20 p-2";
|
||||
case "custom":
|
||||
return "";
|
||||
case "regular":
|
||||
default:
|
||||
return "h-10 w-10 p-2";
|
||||
}
|
||||
}
|
||||
@@ -22,6 +22,7 @@ type CodeBlockProps = {
|
||||
className?: string;
|
||||
};
|
||||
|
||||
//todo change to use CodeHike
|
||||
export default function CodeBlock({
|
||||
code,
|
||||
language = "typescript",
|
||||
|
||||
@@ -1,79 +0,0 @@
|
||||
import { javascript } from "@codemirror/lang-javascript";
|
||||
import type { ViewUpdate } from "@codemirror/view";
|
||||
import type {
|
||||
ReactCodeMirrorProps,
|
||||
UseCodeMirror,
|
||||
} from "@uiw/react-codemirror";
|
||||
import { useCodeMirror } from "@uiw/react-codemirror";
|
||||
import classNames from "classnames";
|
||||
import { useRef, useEffect } from "react";
|
||||
import { getEditorSetup } from "./codeMirrorSetup";
|
||||
import { darkTheme } from "./codeMirrorTheme";
|
||||
|
||||
export interface CodeEditorProps extends Omit<ReactCodeMirrorProps, "onBlur"> {
|
||||
content: string;
|
||||
language?: "typescript" | "shell";
|
||||
showLineNumbers?: boolean;
|
||||
showHighlights?: boolean;
|
||||
readOnly?: boolean;
|
||||
onChange?: (value: string) => void;
|
||||
onUpdate?: (update: ViewUpdate) => void;
|
||||
onBlur?: (code: string) => void;
|
||||
}
|
||||
|
||||
type CodeEditorDefaultProps = Partial<CodeEditorProps>;
|
||||
|
||||
const defaultProps: CodeEditorDefaultProps = {
|
||||
language: "typescript",
|
||||
showLineNumbers: true,
|
||||
showHighlights: true,
|
||||
readOnly: true,
|
||||
basicSetup: false,
|
||||
};
|
||||
|
||||
export function CodeEditor(opts: CodeEditorProps) {
|
||||
const { content, readOnly, onChange, onUpdate, onBlur } = {
|
||||
...defaultProps,
|
||||
...opts,
|
||||
};
|
||||
|
||||
const extensions = getEditorSetup(opts.showLineNumbers, opts.showHighlights);
|
||||
|
||||
if (opts.language === "typescript") {
|
||||
extensions.push(javascript({ typescript: true }));
|
||||
}
|
||||
|
||||
const editor = useRef<HTMLDivElement>(null);
|
||||
const settings: Omit<UseCodeMirror, "onBlur"> = {
|
||||
...opts,
|
||||
container: editor.current,
|
||||
extensions,
|
||||
editable: !readOnly,
|
||||
contentEditable: !readOnly,
|
||||
value: content,
|
||||
autoFocus: false,
|
||||
theme: darkTheme(),
|
||||
indentWithTab: false,
|
||||
basicSetup: false,
|
||||
onChange,
|
||||
onUpdate,
|
||||
};
|
||||
const { setContainer } = useCodeMirror(settings);
|
||||
|
||||
useEffect(() => {
|
||||
if (editor.current) {
|
||||
setContainer(editor.current);
|
||||
}
|
||||
}, [setContainer]);
|
||||
|
||||
return (
|
||||
<div
|
||||
className={classNames("no-scrollbar overflow-y-auto", opts.className)}
|
||||
ref={editor}
|
||||
onBlur={() => {
|
||||
if (!onBlur) return;
|
||||
onBlur(editor.current?.textContent ?? "");
|
||||
}}
|
||||
/>
|
||||
);
|
||||
}
|
||||
@@ -13,7 +13,7 @@ import {
|
||||
SheetTitle,
|
||||
SheetTrigger,
|
||||
} from "../primitives/Sheet";
|
||||
import { Header3 } from "../primitives/text/Headers";
|
||||
import { Header3 } from "../primitives/Headers";
|
||||
import { Input } from "../primitives/Input";
|
||||
import { Badge } from "../primitives/Badge";
|
||||
|
||||
|
||||
@@ -1,15 +0,0 @@
|
||||
import type { ServiceMetadata } from "@trigger.dev/integration-sdk";
|
||||
|
||||
export function IntegrationIcon({
|
||||
integration,
|
||||
}: {
|
||||
integration: ServiceMetadata;
|
||||
}) {
|
||||
return (
|
||||
<img
|
||||
src={integration.icon}
|
||||
alt={integration.name}
|
||||
className="h-5 w-5 shadow-lg transition group-hover:opacity-80"
|
||||
/>
|
||||
);
|
||||
}
|
||||
@@ -1,68 +0,0 @@
|
||||
import { Link } from "@remix-run/react";
|
||||
import classNames from "classnames";
|
||||
import invariant from "tiny-invariant";
|
||||
import type { ConnectionSlot } from "~/hooks/useConnectionSlots";
|
||||
import { useCurrentOrganization } from "~/hooks/useOrganizations";
|
||||
import { ApiLogoIcon } from "../code/ApiLogoIcon";
|
||||
import { List } from "../layout/List";
|
||||
import { Header3 } from "../primitives/text/Headers";
|
||||
import { SubTitle } from "../primitives/text/SubTitle";
|
||||
import { ConnectionSelector } from "./ConnectionSelector";
|
||||
|
||||
export function WorkflowConnections({
|
||||
className,
|
||||
connectionSlots,
|
||||
}: {
|
||||
className?: string;
|
||||
connectionSlots: (ConnectionSlot & { type: "source" | "service" })[];
|
||||
}) {
|
||||
const organization = useCurrentOrganization();
|
||||
invariant(organization, "Organization not found");
|
||||
|
||||
return (
|
||||
<div className={classNames(className)}>
|
||||
<SubTitle>API Connections</SubTitle>
|
||||
<List>
|
||||
{connectionSlots.map((slot) => (
|
||||
<li
|
||||
key={slot.id}
|
||||
className={classNames(
|
||||
slot.connection === null
|
||||
? "!border !border-rose-600 bg-rose-500/10"
|
||||
: "",
|
||||
"flex w-full items-center gap-4 px-4 py-4 first:rounded-t-md last:rounded-b-md"
|
||||
)}
|
||||
>
|
||||
<ApiLogoIcon integration={slot.integration} size="regular" />
|
||||
<div className="flex w-full items-center justify-between">
|
||||
<Header3 size="small" className="truncate text-slate-300">
|
||||
{slot.integration?.name}
|
||||
</Header3>
|
||||
<ConnectionSelector
|
||||
type={slot.type}
|
||||
sourceServiceId={slot.id}
|
||||
organizationId={organization.id}
|
||||
integration={slot.integration}
|
||||
connections={slot.possibleConnections}
|
||||
selectedConnectionId={slot.connection?.id}
|
||||
className="mr-1"
|
||||
popoverAlign="right"
|
||||
/>
|
||||
</div>
|
||||
</li>
|
||||
))}
|
||||
<li className="p-4 pl-5 text-sm text-slate-500">
|
||||
You will be able to authenticate APIs on demand when your workflow
|
||||
runs. You can also{" "}
|
||||
<Link
|
||||
to={`/orgs/${organization.slug}/integrations`}
|
||||
className="text-slate-500 underline decoration-slate-500 underline-offset-4 transition hover:text-slate-400"
|
||||
>
|
||||
connect them now
|
||||
</Link>
|
||||
.
|
||||
</li>
|
||||
</List>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
@@ -1,60 +0,0 @@
|
||||
import classNames from "classnames";
|
||||
|
||||
export function AppLayoutThreeCol({ children }: { children: React.ReactNode }) {
|
||||
return (
|
||||
<div className="grid h-full w-full grid-cols-[3.5rem_auto]">{children}</div>
|
||||
);
|
||||
}
|
||||
|
||||
export function AppLayoutTwoCol({ children }: { children: React.ReactNode }) {
|
||||
return (
|
||||
<div className="grid h-full w-full grid-cols-[16rem_auto] overflow-hidden">
|
||||
{children}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
export function AppBody({
|
||||
children,
|
||||
className = "bg-slate-850",
|
||||
}: {
|
||||
children: React.ReactNode;
|
||||
className?: string;
|
||||
}) {
|
||||
return (
|
||||
<div
|
||||
className={classNames(
|
||||
"grid h-full grid-rows-[3.6rem_auto] overflow-hidden",
|
||||
className
|
||||
)}
|
||||
>
|
||||
{children}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
export function PublicAppLayout({ children }: { children: React.ReactNode }) {
|
||||
return (
|
||||
<div className="grid h-full w-full grid-rows-[4rem_auto] overflow-y-auto">
|
||||
{children}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
export function LoggedInAppLayout({ children }: { children: React.ReactNode }) {
|
||||
return (
|
||||
<div className="grid h-full w-full grid-rows-[3.6rem_auto] overflow-hidden">
|
||||
{children}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
export function PublicAppBody({
|
||||
children,
|
||||
className = "bg-slate-850",
|
||||
}: {
|
||||
children: React.ReactNode;
|
||||
className?: string;
|
||||
}) {
|
||||
return <div className={classNames("", className)}>{children}</div>;
|
||||
}
|
||||
@@ -1,17 +0,0 @@
|
||||
import classNames from "classnames";
|
||||
|
||||
const baseClasses = "px-4 py-4 md:px-8 md:py-6 lg:px-12 lg:py-10";
|
||||
|
||||
export function Container({
|
||||
children,
|
||||
className,
|
||||
}: {
|
||||
children: React.ReactNode;
|
||||
className?: string;
|
||||
}) {
|
||||
return (
|
||||
<div className={classNames("overflow-y-auto", baseClasses, className)}>
|
||||
{children}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
@@ -1,49 +0,0 @@
|
||||
const linkStyle =
|
||||
"text-xs font-medium text-slate-400 whitespace-nowrap bg-transparent text-slate-500 transition hover:text-indigo-500";
|
||||
|
||||
export function Footer() {
|
||||
return (
|
||||
<div className="flex w-full flex-col items-center justify-between border-t border-slate-800 bg-slate-950 py-4 pl-2 pr-3 sm:flex-row sm:py-4">
|
||||
<div className="flex gap-2 pb-4 text-xs text-slate-500 sm:pb-0">
|
||||
<p>© {new Date().getFullYear()} Trigger.dev </p>
|
||||
<span className="text-slate-600">|</span>{" "}
|
||||
<a
|
||||
className="transition hover:text-indigo-500"
|
||||
href="https://trigger.dev/legal/terms"
|
||||
>
|
||||
Terms
|
||||
</a>{" "}
|
||||
<span className="text-slate-600">|</span>{" "}
|
||||
<a
|
||||
className="transition hover:text-indigo-500"
|
||||
href="https://trigger.dev/legal/privacy"
|
||||
>
|
||||
Privacy
|
||||
</a>
|
||||
</div>
|
||||
|
||||
<div className="flex gap-3">
|
||||
<a
|
||||
target="_blank"
|
||||
rel="noopener noreferrer"
|
||||
href="https://discord.gg/kA47vcd8P6"
|
||||
className={linkStyle}
|
||||
>
|
||||
Discord
|
||||
</a>
|
||||
<a
|
||||
target="_blank"
|
||||
rel="noopener noreferrer"
|
||||
href="https://twitter.com/triggerdotdev"
|
||||
className={linkStyle}
|
||||
>
|
||||
Twitter
|
||||
</a>
|
||||
|
||||
<a href="mailto:hello@trigger.dev" className={linkStyle}>
|
||||
Get in touch
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
@@ -1,20 +0,0 @@
|
||||
export type PanelProps = {
|
||||
children: React.ReactNode;
|
||||
className?: string;
|
||||
};
|
||||
|
||||
export function Panel({
|
||||
children,
|
||||
className,
|
||||
}: {
|
||||
children: React.ReactNode;
|
||||
className?: string;
|
||||
}) {
|
||||
return (
|
||||
<div
|
||||
className={`bg-slate-800 w-full shadow-md rounded-md p-3 ${className}`}
|
||||
>
|
||||
{children}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
@@ -1,76 +0,0 @@
|
||||
import { ArrowRightIcon } from "@heroicons/react/24/outline";
|
||||
import type { ReactNode } from "react";
|
||||
import { dateDifference, formatDateTime } from "~/utils";
|
||||
import { Body } from "../primitives/text/Body";
|
||||
|
||||
const workflowNodeFlexClasses = "flex gap-1 items-baseline";
|
||||
const workflowNodeUppercaseClasses = "uppercase text-slate-400";
|
||||
|
||||
export function PanelHeader({
|
||||
icon,
|
||||
title,
|
||||
startedAt,
|
||||
finishedAt,
|
||||
integration,
|
||||
runId,
|
||||
name,
|
||||
}: {
|
||||
icon: ReactNode;
|
||||
title: string;
|
||||
startedAt?: Date | null;
|
||||
finishedAt?: Date | null;
|
||||
integration?: string;
|
||||
runId?: string;
|
||||
name?: string;
|
||||
}) {
|
||||
return (
|
||||
<div className="flex mb-4 pb-3 justify-between items-center border-b border-slate-850">
|
||||
<div className="flex gap-1 items-center">
|
||||
{icon}
|
||||
<Body size="small" className="uppercase text-slate-400 font-semibold">
|
||||
{title}
|
||||
</Body>
|
||||
{name && (
|
||||
<div className="flex gap-3 items-center ml-2">
|
||||
<span className="block h-5 border-l border-slate-850"></span>
|
||||
<Body size="small" className="text-slate-400">
|
||||
{name}
|
||||
</Body>
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
<ul className="flex justify-end items-center gap-4">
|
||||
<div className={workflowNodeFlexClasses}>
|
||||
{startedAt && (
|
||||
<Body size="small">{formatDateTime(startedAt, "long")}</Body>
|
||||
)}
|
||||
{startedAt &&
|
||||
finishedAt &&
|
||||
dateDifference(startedAt, finishedAt) > 1000 && (
|
||||
<>
|
||||
<Body
|
||||
size="extra-small"
|
||||
className={workflowNodeUppercaseClasses}
|
||||
>
|
||||
<ArrowRightIcon className="h-3 w-3" />
|
||||
</Body>
|
||||
<Body size="small">{formatDateTime(finishedAt, "long")}</Body>
|
||||
</>
|
||||
)}
|
||||
</div>
|
||||
|
||||
{integration && (
|
||||
<li className="flex gap-2 items-center">
|
||||
<Body size="small">{integration}</Body>
|
||||
</li>
|
||||
)}
|
||||
|
||||
{runId && (
|
||||
<li className="flex gap-2 items-center">
|
||||
<Body size="small">{runId}</Body>
|
||||
</li>
|
||||
)}
|
||||
</ul>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
@@ -1,96 +0,0 @@
|
||||
import { InformationCircleIcon } from "@heroicons/react/24/solid";
|
||||
import { Spinner } from "../primitives/Spinner";
|
||||
import { Body } from "../primitives/text/Body";
|
||||
|
||||
export type PanelInfoProps = {
|
||||
children: React.ReactNode;
|
||||
className?: string;
|
||||
};
|
||||
|
||||
export function PanelInfo({
|
||||
children,
|
||||
className,
|
||||
message,
|
||||
}: {
|
||||
children?: React.ReactNode;
|
||||
className?: string;
|
||||
message?: string;
|
||||
}) {
|
||||
return (
|
||||
<IconPanel
|
||||
className={className}
|
||||
message={message}
|
||||
icon={
|
||||
<InformationCircleIcon className="h-6 w-6 min-w-[24px] text-blue-500" />
|
||||
}
|
||||
>
|
||||
{children}
|
||||
</IconPanel>
|
||||
);
|
||||
}
|
||||
|
||||
export function PanelWarning({
|
||||
children,
|
||||
className,
|
||||
message,
|
||||
}: {
|
||||
children?: React.ReactNode;
|
||||
className?: string;
|
||||
message?: string;
|
||||
}) {
|
||||
return (
|
||||
<IconPanel
|
||||
className={className}
|
||||
message={message}
|
||||
icon={
|
||||
<InformationCircleIcon className="h-6 w-6 min-w-[24px] text-yellow-500" />
|
||||
}
|
||||
>
|
||||
{children}
|
||||
</IconPanel>
|
||||
);
|
||||
}
|
||||
|
||||
export function PanelLoading({
|
||||
children,
|
||||
className,
|
||||
message,
|
||||
}: {
|
||||
children?: React.ReactNode;
|
||||
className?: string;
|
||||
message?: string;
|
||||
}) {
|
||||
return (
|
||||
<IconPanel
|
||||
className={className}
|
||||
message={message}
|
||||
icon={<Spinner className="h-6 w-6 min-w-[24px]" />}
|
||||
>
|
||||
{children}
|
||||
</IconPanel>
|
||||
);
|
||||
}
|
||||
|
||||
export function IconPanel({
|
||||
children,
|
||||
className,
|
||||
message,
|
||||
icon,
|
||||
}: {
|
||||
children?: React.ReactNode;
|
||||
className?: string;
|
||||
message?: string;
|
||||
icon: React.ReactNode;
|
||||
}) {
|
||||
return (
|
||||
<div
|
||||
className={`flex w-full gap-4 rounded-md border border-slate-600 bg-slate-400/10 py-3 pl-3 pr-4 shadow-md backdrop-blur-sm ${className}`}
|
||||
>
|
||||
<div className="flex items-center justify-start gap-2.5">
|
||||
{icon}
|
||||
<Body className="text-slate-300">{message}</Body>
|
||||
</div>
|
||||
{children}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
@@ -1,29 +0,0 @@
|
||||
import { ExclamationTriangleIcon } from "@heroicons/react/24/solid";
|
||||
import { Body } from "../primitives/text/Body";
|
||||
|
||||
export type PanelWarningProps = {
|
||||
children: React.ReactNode;
|
||||
className?: string;
|
||||
};
|
||||
|
||||
export function PanelWarning({
|
||||
children,
|
||||
className,
|
||||
message,
|
||||
}: {
|
||||
children?: React.ReactNode;
|
||||
className?: string;
|
||||
message: string;
|
||||
}) {
|
||||
return (
|
||||
<div
|
||||
className={`flex w-full items-center rounded-md border border-amber-500 bg-amber-400/10 p-3 shadow-md ${className}`}
|
||||
>
|
||||
<div className="flex items-center gap-2.5">
|
||||
<ExclamationTriangleIcon className="h-6 w-6 min-w-[24px] text-amber-500" />
|
||||
<Body className="">{message}</Body>
|
||||
</div>
|
||||
{children}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
+5
-5
@@ -1,7 +1,7 @@
|
||||
import { Popover, Transition } from "@headlessui/react";
|
||||
import {
|
||||
ChevronUpDownIcon,
|
||||
ArrowsRightLeftIcon,
|
||||
ChevronUpDownIcon,
|
||||
} from "@heroicons/react/24/outline";
|
||||
import {
|
||||
CheckIcon,
|
||||
@@ -13,13 +13,13 @@ import classNames from "classnames";
|
||||
import { Fragment } from "react";
|
||||
import { useCurrentOrganization } from "~/hooks/useOrganizations";
|
||||
import { useCurrentWorkflow, useWorkflows } from "~/hooks/useWorkflows";
|
||||
import { BreadcrumbDivider } from "../layout/Header";
|
||||
import { PrimaryLink } from "../primitives/Buttons";
|
||||
import { MobileNavIcon, MobileNavLink } from "../primitives/NavLink";
|
||||
import { BreadcrumbDivider } from "./NavBar";
|
||||
|
||||
const dimmedClassNames = "text-slate-500";
|
||||
|
||||
export function WorkflowMenu() {
|
||||
//todo change to jobs
|
||||
//todo change to use popover
|
||||
export function JobsMenu() {
|
||||
const workflows = useWorkflows();
|
||||
const currentWorkflow = useCurrentWorkflow();
|
||||
const currentOrganization = useCurrentOrganization();
|
||||
+47
-28
@@ -4,43 +4,35 @@ import {
|
||||
ChatBubbleLeftRightIcon,
|
||||
} from "@heroicons/react/24/outline";
|
||||
import { Fragment } from "react";
|
||||
import { ProjectMenu } from "~/features/ee/projects/components/ProjectMenu";
|
||||
import { Logo } from "../Logo";
|
||||
import { OrganizationMenu } from "../navigation/OrganizationMenu";
|
||||
import { WorkflowMenu } from "../navigation/WorkflowMenu";
|
||||
import {
|
||||
PrimaryA,
|
||||
PrimaryButton,
|
||||
SecondaryA,
|
||||
SecondaryButton,
|
||||
SecondaryLink,
|
||||
} from "../primitives/Buttons";
|
||||
import { MobileNavIcon } from "../primitives/NavLink";
|
||||
import { ProjectsMenu } from "./ProjectsMenu";
|
||||
import { JobsMenu } from "./JobsMenu";
|
||||
import { Button, LinkButton } from "../primitives";
|
||||
|
||||
type HeaderProps = {
|
||||
children?: React.ReactNode;
|
||||
context: "workflows" | "projects";
|
||||
};
|
||||
|
||||
export function Header({ children, context }: HeaderProps) {
|
||||
export function NavBar() {
|
||||
return (
|
||||
<div className="z-50 flex h-[3.6rem] w-full items-center gap-2 border-b border-slate-800 bg-slate-950 py-1 pl-2 pr-2.5">
|
||||
<div className="hidden items-center lg:flex">
|
||||
<OrganizationMenu />
|
||||
{context === "workflows" ? <WorkflowMenu /> : <ProjectMenu />}
|
||||
<ProjectsMenu />
|
||||
<JobsMenu />
|
||||
</div>
|
||||
<Logo className="ml-1 w-36 lg:hidden" />
|
||||
<div className="flex flex-1 justify-center">{children}</div>
|
||||
<MobileDropdownMenu />
|
||||
<div className="hidden items-center gap-2 sm:flex">
|
||||
<SecondaryA href="https://docs.trigger.dev" target="_blank">
|
||||
<ArrowTopRightOnSquareIcon className="-ml-1 h-4 w-4" />
|
||||
Documentation
|
||||
</SecondaryA>
|
||||
<SecondaryButton data-attr="posthog-feedback-button">
|
||||
<ChatBubbleLeftRightIcon className="-ml-1 h-4 w-4" />
|
||||
Send us feedback
|
||||
</SecondaryButton>
|
||||
<LinkButton
|
||||
to="https://docs.trigger.dev"
|
||||
text="Documentation"
|
||||
size="medium"
|
||||
theme="secondary"
|
||||
LeadingIcon={ArrowTopRightOnSquareIcon}
|
||||
/>
|
||||
<Button
|
||||
text="Send us feedback"
|
||||
size="medium"
|
||||
theme="secondary"
|
||||
data-attr="posthog-feedback-button"
|
||||
LeadingIcon={ChatBubbleLeftRightIcon}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
@@ -126,3 +118,30 @@ function MobileDropdownMenu() {
|
||||
</Popover>
|
||||
);
|
||||
}
|
||||
|
||||
function MobileNavIcon({ open }: { open: boolean }) {
|
||||
return (
|
||||
<svg
|
||||
aria-hidden="true"
|
||||
className="h-3.5 w-3.5 overflow-visible stroke-slate-300"
|
||||
fill="none"
|
||||
strokeWidth={2}
|
||||
strokeLinecap="round"
|
||||
>
|
||||
<path
|
||||
d="M0 1H14M0 7H14M0 13H14"
|
||||
className={classnames(
|
||||
"origin-center transition",
|
||||
open && "scale-90 opacity-0"
|
||||
)}
|
||||
/>
|
||||
<path
|
||||
d="M2 2L12 12M12 2L2 12"
|
||||
className={classnames(
|
||||
"origin-center transition",
|
||||
!open && "scale-90 opacity-0"
|
||||
)}
|
||||
/>
|
||||
</svg>
|
||||
);
|
||||
}
|
||||
+3
-3
@@ -1,6 +1,5 @@
|
||||
import { Popover, Transition } from "@headlessui/react";
|
||||
import {
|
||||
BookmarkIcon,
|
||||
BuildingOffice2Icon,
|
||||
ChevronUpDownIcon,
|
||||
UserIcon,
|
||||
@@ -14,12 +13,13 @@ import {
|
||||
useIsNewOrganizationPage,
|
||||
useOrganizations,
|
||||
} from "~/hooks/useOrganizations";
|
||||
import { BreadcrumbDivider } from "../layout/Header";
|
||||
|
||||
const actionClassNames = "text-white";
|
||||
const dimmedClassNames = "text-slate-500";
|
||||
|
||||
export function OrganizationMenu() {
|
||||
//todo change to projects
|
||||
//todo change to use popover
|
||||
export function ProjectsMenu() {
|
||||
const organizations = useOrganizations();
|
||||
const currentOrganization = useCurrentOrganization();
|
||||
const isNewPage = useIsNewOrganizationPage();
|
||||
@@ -23,8 +23,9 @@ import { useOptionalUser } from "~/hooks/useUser";
|
||||
import { LogoIcon } from "../LogoIcon";
|
||||
import { MenuTitleToolTip } from "../primitives/MenuTitleToolTip";
|
||||
import { Body } from "../primitives/text/Body";
|
||||
import { Header1 } from "../primitives/text/Headers";
|
||||
import { Header1 } from "../primitives/Headers";
|
||||
|
||||
//todo change to the new collapsible side menu
|
||||
export function SideMenuContainer({ children }: { children: React.ReactNode }) {
|
||||
return (
|
||||
<div className="grid h-full grid-cols-[16rem_auto] overflow-hidden">
|
||||
|
||||
@@ -1,32 +0,0 @@
|
||||
import { Link } from "@remix-run/react";
|
||||
import { TertiaryLink } from "../primitives/Buttons";
|
||||
import { SubTitle } from "../primitives/text/SubTitle";
|
||||
import { StepNumber } from "./StepNumber";
|
||||
|
||||
export function BackToStep1() {
|
||||
return (
|
||||
<>
|
||||
<SubTitle className="flex items-center">
|
||||
<StepNumber complete />
|
||||
<Link to=".." className="transition hover:text-slate-300">
|
||||
I'll host the workflow myself
|
||||
</Link>
|
||||
</SubTitle>
|
||||
<TertiaryLink to="..">Change answer</TertiaryLink>
|
||||
</>
|
||||
);
|
||||
}
|
||||
|
||||
export function BackToStep2({ text }: { text: string }) {
|
||||
return (
|
||||
<>
|
||||
<SubTitle className="flex items-center">
|
||||
<StepNumber complete />
|
||||
<Link to="../step2" className="transition hover:text-slate-300">
|
||||
{text}
|
||||
</Link>
|
||||
</SubTitle>
|
||||
<TertiaryLink to="../step2">Change answer</TertiaryLink>
|
||||
</>
|
||||
);
|
||||
}
|
||||
@@ -1,7 +0,0 @@
|
||||
export const onboarding = {
|
||||
buttonStyles:
|
||||
"relative flex flex-col cursor-pointer items-center justify-start hover:bg-slate-700 px-4 shadow gap-4 rounded bg-slate-700/50 py-8 border border-slate-700 transition",
|
||||
labelStyles:
|
||||
"absolute top-0 right-0 uppercase text-xs text-slate-900 px-2 py-1 font-semibold rounded-bl rounded-tr",
|
||||
maxWidth: "flex flex-col max-w-4xl",
|
||||
};
|
||||
@@ -1,290 +1,151 @@
|
||||
import type { LinkProps } from "@remix-run/react";
|
||||
import { Link } from "@remix-run/react";
|
||||
import classnames from "classnames";
|
||||
import React from "react";
|
||||
import { cn } from "~/utils/cn";
|
||||
|
||||
type Size = "regular" | "large";
|
||||
const sizes = {
|
||||
small: "h-[24px] px-2 text-xs",
|
||||
medium: "h-[32px] px-2.5 text-sm",
|
||||
large: "h-[40px] px-3 text-base",
|
||||
};
|
||||
|
||||
const commonClasses =
|
||||
"inline-flex items-center justify-center max-w-max rounded transition whitespace-nowrap";
|
||||
export const primaryClasses = classnames(
|
||||
commonClasses,
|
||||
"px-4 py-2 bg-indigo-700 text-white hover:bg-indigo-600 focus-visible:ring-indigo-800 gap-2 disabled:opacity-50 disabled:cursor-not-allowed disabled:bg-slate-700 disabled:text-slate-400"
|
||||
);
|
||||
export const secondaryClasses = classnames(
|
||||
commonClasses,
|
||||
"px-4 py-2 bg-transparent ring-1 ring-slate-700 ring-inset text-white hover:bg-white/5 hover:border-slate-700 focus-visible:ring-slate-300 gap-2"
|
||||
);
|
||||
export const tertiaryClasses = classnames(
|
||||
commonClasses,
|
||||
"text-slate-300/70 hover:text-white gap-1"
|
||||
);
|
||||
export const dangerClasses = classnames(
|
||||
commonClasses,
|
||||
"px-4 py-2 bg-rose-700 text-white hover:bg-rose-600 focus-visible:ring-rose-800 gap-2"
|
||||
);
|
||||
export const toxicClasses = classnames(
|
||||
commonClasses,
|
||||
"hover:cursor-pointer px-3 py-1 transition bg-gradient-to-r from-acid-500 to-toxic-500 text-slate-1000 !text-base font-bold hover:from-acid-600 hover:to-toxic-600 focus-visible:ring-slate-300"
|
||||
);
|
||||
const themes = {
|
||||
primary:
|
||||
"text-slate-900 bg-gradient-primary overflow-hidden hover:opacity-90",
|
||||
secondary:
|
||||
"text-slate-200 bg-gradient-secondary transition duration-500 hover:opacity-90",
|
||||
secondaryOutline:
|
||||
"text-indigo-400 hover:text-indigo-300 border border-indigo-500 focus:ring-indigo-400 py-1/2 hover:border-indigo-400",
|
||||
};
|
||||
|
||||
function getSizeClassName(size: Size) {
|
||||
switch (size) {
|
||||
case "large":
|
||||
return "text-lg";
|
||||
case "regular":
|
||||
default:
|
||||
return "text-sm";
|
||||
const btnVariants = {
|
||||
$all: "text-center font-semibold font-sans justify-center items-center shrink-0 transition-all duration-300 leading-tight rounded select-none group-focus:outline-none group-disabled:opacity-75 group-disabled:pointer-events-none",
|
||||
size: sizes,
|
||||
theme: themes,
|
||||
};
|
||||
|
||||
const iconVariants = {
|
||||
size: {
|
||||
// ExtraSmall: "h-3",
|
||||
small: "h-4",
|
||||
medium: "h-4",
|
||||
large: "h-5",
|
||||
// ExtraLarge: "h-6",
|
||||
},
|
||||
theme: {
|
||||
primary: "text-slate-900",
|
||||
secondary: "text-slate-200",
|
||||
secondaryOutline: "text-indigo-400",
|
||||
},
|
||||
};
|
||||
|
||||
type ButtonContentPropsType = {
|
||||
text?: string | React.ReactNode;
|
||||
LeadingIcon?: React.ComponentType<any>;
|
||||
TrailingIcon?: React.ComponentType<any>;
|
||||
fullWidth?: boolean;
|
||||
className?: string;
|
||||
size: keyof typeof sizes;
|
||||
theme: keyof typeof themes;
|
||||
};
|
||||
|
||||
function ButtonContent(props: ButtonContentPropsType) {
|
||||
const { text, LeadingIcon, TrailingIcon, fullWidth, className } = props;
|
||||
|
||||
// Based on the size prop, we'll use the corresponding variant classnames
|
||||
const btnClassName = `${btnVariants.$all} ${btnVariants.size[props.size]} ${
|
||||
btnVariants.theme[props.theme]
|
||||
}`;
|
||||
const iconClassName = `${iconVariants.size[props.size]} ${
|
||||
iconVariants.theme[props.theme]
|
||||
}`;
|
||||
return (
|
||||
<div
|
||||
className={cn(
|
||||
className,
|
||||
fullWidth ? "flex" : "inline-flex",
|
||||
btnClassName
|
||||
)}
|
||||
>
|
||||
<div className="flex w-full items-center gap-x-1">
|
||||
{LeadingIcon && (
|
||||
<LeadingIcon
|
||||
className={cn(iconClassName, "shrink-0 justify-start")}
|
||||
/>
|
||||
)}
|
||||
|
||||
{text && <span className="mx-auto self-center truncate">{text}</span>}
|
||||
|
||||
{TrailingIcon && (
|
||||
<TrailingIcon className={cn(iconClassName, "shrink-0 justify-end")} />
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
type ButtonPropsType = Pick<
|
||||
JSX.IntrinsicElements["button"],
|
||||
"type" | "disabled" | "onClick" | "name" | "value"
|
||||
> &
|
||||
React.ComponentProps<typeof ButtonContent>;
|
||||
export const Button = ({
|
||||
type,
|
||||
disabled,
|
||||
onClick,
|
||||
...props
|
||||
}: ButtonPropsType) => {
|
||||
return (
|
||||
<button
|
||||
className={cn("group outline-none", props.fullWidth ? "w-full" : "")}
|
||||
type={type}
|
||||
disabled={disabled}
|
||||
onClick={onClick}
|
||||
name={props.name}
|
||||
value={props.value}
|
||||
>
|
||||
<ButtonContent {...props} />
|
||||
</button>
|
||||
);
|
||||
};
|
||||
|
||||
type LinkPropsType = Pick<LinkProps, "to"> &
|
||||
React.ComponentProps<typeof ButtonContent>;
|
||||
export const LinkButton = ({ to, ...props }: LinkPropsType) => {
|
||||
if (to.toString().startsWith("http")) {
|
||||
return (
|
||||
<ExtLink
|
||||
href={to.toString()}
|
||||
className={cn("group outline-none", props.fullWidth ? "w-full" : "")}
|
||||
>
|
||||
<ButtonContent {...props} />
|
||||
</ExtLink>
|
||||
);
|
||||
} else {
|
||||
return (
|
||||
<Link
|
||||
to={to}
|
||||
className={cn("group outline-none", props.fullWidth ? "w-full" : "")}
|
||||
>
|
||||
<ButtonContent {...props} />
|
||||
</Link>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
type ButtonProps = React.DetailedHTMLProps<
|
||||
React.ButtonHTMLAttributes<HTMLButtonElement>,
|
||||
HTMLButtonElement
|
||||
> & {
|
||||
size?: Size;
|
||||
};
|
||||
|
||||
type LinkProps = Parameters<typeof Link>[0] & {
|
||||
size?: Size;
|
||||
type ExtLinkProps = JSX.IntrinsicElements["a"] & {
|
||||
children: React.ReactNode;
|
||||
className?: string;
|
||||
href: string;
|
||||
};
|
||||
|
||||
type AProps = React.DetailedHTMLProps<
|
||||
React.AnchorHTMLAttributes<HTMLAnchorElement>,
|
||||
HTMLAnchorElement
|
||||
> & {
|
||||
size?: Size;
|
||||
};
|
||||
|
||||
export function PrimaryButton({
|
||||
children,
|
||||
size = "regular",
|
||||
className,
|
||||
...props
|
||||
}: ButtonProps) {
|
||||
return (
|
||||
<button
|
||||
className={classnames(primaryClasses, getSizeClassName(size), className)}
|
||||
{...props}
|
||||
>
|
||||
{children}
|
||||
</button>
|
||||
);
|
||||
}
|
||||
|
||||
export function SecondaryButton({
|
||||
children,
|
||||
size = "regular",
|
||||
className,
|
||||
...props
|
||||
}: ButtonProps) {
|
||||
return (
|
||||
<button
|
||||
className={classnames(
|
||||
secondaryClasses,
|
||||
getSizeClassName(size),
|
||||
className
|
||||
)}
|
||||
{...props}
|
||||
>
|
||||
{children}
|
||||
</button>
|
||||
);
|
||||
}
|
||||
|
||||
export function TertiaryButton({
|
||||
children,
|
||||
size = "regular",
|
||||
className,
|
||||
...props
|
||||
}: ButtonProps) {
|
||||
return (
|
||||
<button
|
||||
className={classnames(tertiaryClasses, getSizeClassName(size), className)}
|
||||
{...props}
|
||||
>
|
||||
{children}
|
||||
</button>
|
||||
);
|
||||
}
|
||||
|
||||
export function DangerButton({
|
||||
children,
|
||||
size = "regular",
|
||||
className,
|
||||
...props
|
||||
}: ButtonProps) {
|
||||
return (
|
||||
<button
|
||||
className={classnames(dangerClasses, getSizeClassName(size), className)}
|
||||
{...props}
|
||||
>
|
||||
{children}
|
||||
</button>
|
||||
);
|
||||
}
|
||||
|
||||
export function PrimaryLink({
|
||||
children,
|
||||
size = "regular",
|
||||
className,
|
||||
to,
|
||||
...props
|
||||
}: LinkProps) {
|
||||
return (
|
||||
<Link
|
||||
to={to}
|
||||
className={classnames(primaryClasses, getSizeClassName(size), className)}
|
||||
{...props}
|
||||
>
|
||||
{children}
|
||||
</Link>
|
||||
);
|
||||
}
|
||||
|
||||
export function SecondaryLink({
|
||||
children,
|
||||
className,
|
||||
size = "regular",
|
||||
to,
|
||||
...props
|
||||
}: LinkProps) {
|
||||
return (
|
||||
<Link
|
||||
to={to}
|
||||
className={classnames(
|
||||
secondaryClasses,
|
||||
getSizeClassName(size),
|
||||
className
|
||||
)}
|
||||
{...props}
|
||||
>
|
||||
{children}
|
||||
</Link>
|
||||
);
|
||||
}
|
||||
|
||||
export function TertiaryLink({
|
||||
children,
|
||||
className,
|
||||
size = "regular",
|
||||
to,
|
||||
...props
|
||||
}: LinkProps) {
|
||||
return (
|
||||
<Link
|
||||
to={to}
|
||||
className={classnames(tertiaryClasses, getSizeClassName(size), className)}
|
||||
{...props}
|
||||
>
|
||||
{children}
|
||||
</Link>
|
||||
);
|
||||
}
|
||||
|
||||
export function DangerLink({
|
||||
children,
|
||||
className,
|
||||
size = "regular",
|
||||
to,
|
||||
...props
|
||||
}: LinkProps) {
|
||||
return (
|
||||
<Link
|
||||
to={to}
|
||||
className={classnames(dangerClasses, getSizeClassName(size), className)}
|
||||
{...props}
|
||||
>
|
||||
{children}
|
||||
</Link>
|
||||
);
|
||||
}
|
||||
|
||||
export function ToxicLink({
|
||||
children,
|
||||
className,
|
||||
size = "regular",
|
||||
to,
|
||||
...props
|
||||
}: LinkProps) {
|
||||
return (
|
||||
<Link
|
||||
to={to}
|
||||
className={classnames(toxicClasses, getSizeClassName(size), className)}
|
||||
{...props}
|
||||
>
|
||||
{children}
|
||||
</Link>
|
||||
);
|
||||
}
|
||||
|
||||
export function PrimaryA({
|
||||
children,
|
||||
className,
|
||||
size = "regular",
|
||||
href,
|
||||
...props
|
||||
}: AProps) {
|
||||
function ExtLink({ className, href, children, ...props }: ExtLinkProps) {
|
||||
return (
|
||||
<a
|
||||
className={cn(className)}
|
||||
target="_blank"
|
||||
rel="noopener noreferrer"
|
||||
href={href}
|
||||
className={classnames(primaryClasses, getSizeClassName(size), className)}
|
||||
{...props}
|
||||
>
|
||||
{children}
|
||||
</a>
|
||||
);
|
||||
}
|
||||
|
||||
export function SecondaryA({
|
||||
children,
|
||||
className,
|
||||
size = "regular",
|
||||
href,
|
||||
...props
|
||||
}: AProps) {
|
||||
return (
|
||||
<a
|
||||
href={href}
|
||||
className={classnames(
|
||||
secondaryClasses,
|
||||
getSizeClassName(size),
|
||||
className
|
||||
)}
|
||||
{...props}
|
||||
>
|
||||
{children}
|
||||
</a>
|
||||
);
|
||||
}
|
||||
|
||||
export function TertiaryA({
|
||||
children,
|
||||
className,
|
||||
size = "regular",
|
||||
href,
|
||||
...props
|
||||
}: AProps) {
|
||||
return (
|
||||
<a
|
||||
href={href}
|
||||
className={classnames(tertiaryClasses, getSizeClassName(size), className)}
|
||||
{...props}
|
||||
>
|
||||
{children}
|
||||
</a>
|
||||
);
|
||||
}
|
||||
|
||||
export function ToxicA({
|
||||
children,
|
||||
className,
|
||||
size = "regular",
|
||||
href,
|
||||
...props
|
||||
}: AProps) {
|
||||
return (
|
||||
<a
|
||||
href={href}
|
||||
className={classnames(toxicClasses, getSizeClassName(size), className)}
|
||||
{...props}
|
||||
>
|
||||
{children}
|
||||
|
||||
@@ -5,6 +5,7 @@ type DialogProps = Parameters<typeof HeadlessDialog>[0] & {
|
||||
children: React.ReactNode;
|
||||
};
|
||||
|
||||
//todo change to use ShadCn
|
||||
function Dialog({ onClose, children, ...props }: DialogProps) {
|
||||
return (
|
||||
<Transition {...props}>
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
import type { z } from "zod";
|
||||
|
||||
//todo use a new Input Field Error component
|
||||
export function FormError({
|
||||
errors,
|
||||
path,
|
||||
@@ -20,7 +21,7 @@ export function FormError({
|
||||
}
|
||||
|
||||
return (
|
||||
<div className="mt-2 text-sm text-red-600 col-span-full">
|
||||
<div className="col-span-full mt-2 text-sm text-red-600">
|
||||
{relevantErrors.map((error, index) => (
|
||||
<p key={index}>{error.message}</p>
|
||||
))}
|
||||
|
||||
@@ -0,0 +1,127 @@
|
||||
import { cn } from "~/utils/cn";
|
||||
|
||||
const header1Variants = {
|
||||
"small/bold": "font-title font-bold text-3xl pb-4",
|
||||
"base/bold": "font-title font-bold text-4xl pb-4",
|
||||
"large/bold": "font-title font-bold sm:text-5xl sm:pb-8 text-4xl pb-6",
|
||||
};
|
||||
|
||||
const header2Variants = {
|
||||
"small/bold": "font-title font-bold text-2xl pb-4",
|
||||
"base/bold": "font-title font-bold text-3xl pb-4",
|
||||
"large/bold": "font-title font-bold text-4xl pb-6",
|
||||
};
|
||||
|
||||
const header3Variants = {
|
||||
"small/semibold": "font-title font-semibold text-xl pb-2",
|
||||
"base/semibold": "font-title font-semibold text-2xl pb-2",
|
||||
"large/semibold": "font-title font-semibold text-3xl pb-4",
|
||||
};
|
||||
|
||||
const header4Variants = {
|
||||
"small/semibold": "font-title font-semibold text-lg pb-2",
|
||||
"base/semibold": "font-title font-semibold text-xl pb-2",
|
||||
"large/semibold": "font-title font-semibold text-2xl pb-4",
|
||||
};
|
||||
|
||||
type HeaderProps = {
|
||||
className?: string;
|
||||
children: React.ReactNode;
|
||||
textCenter?: boolean;
|
||||
};
|
||||
|
||||
type Header1Props = HeaderProps & {
|
||||
variant: keyof typeof header1Variants;
|
||||
};
|
||||
|
||||
type Header2Props = HeaderProps & {
|
||||
variant: keyof typeof header2Variants;
|
||||
};
|
||||
|
||||
type Header3Props = HeaderProps & {
|
||||
variant: keyof typeof header3Variants;
|
||||
};
|
||||
|
||||
type Header4Props = HeaderProps & {
|
||||
variant: keyof typeof header4Variants;
|
||||
};
|
||||
|
||||
export function Header1({
|
||||
variant,
|
||||
textCenter,
|
||||
className,
|
||||
children,
|
||||
}: Header1Props) {
|
||||
return (
|
||||
<h1
|
||||
className={cn(
|
||||
"text-slate-200",
|
||||
header1Variants[variant],
|
||||
textCenter ? "text-center" : "",
|
||||
className
|
||||
)}
|
||||
>
|
||||
{children}
|
||||
</h1>
|
||||
);
|
||||
}
|
||||
|
||||
export function Header2({
|
||||
variant,
|
||||
textCenter,
|
||||
className,
|
||||
children,
|
||||
}: Header2Props) {
|
||||
return (
|
||||
<h2
|
||||
className={cn(
|
||||
"text-slate-200",
|
||||
textCenter ? "text-center" : "",
|
||||
header2Variants[variant],
|
||||
className
|
||||
)}
|
||||
>
|
||||
{children}
|
||||
</h2>
|
||||
);
|
||||
}
|
||||
|
||||
export function Header3({
|
||||
variant,
|
||||
textCenter,
|
||||
className,
|
||||
children,
|
||||
}: Header3Props) {
|
||||
return (
|
||||
<h3
|
||||
className={cn(
|
||||
"text-slate-200",
|
||||
textCenter ? "text-center" : "",
|
||||
header3Variants[variant],
|
||||
className
|
||||
)}
|
||||
>
|
||||
{children}
|
||||
</h3>
|
||||
);
|
||||
}
|
||||
|
||||
export function Header4({
|
||||
variant,
|
||||
textCenter,
|
||||
className,
|
||||
children,
|
||||
}: Header4Props) {
|
||||
return (
|
||||
<h4
|
||||
className={cn(
|
||||
"text-slate-200",
|
||||
textCenter ? "text-center" : "",
|
||||
header4Variants[variant],
|
||||
className
|
||||
)}
|
||||
>
|
||||
{children}
|
||||
</h4>
|
||||
);
|
||||
}
|
||||
@@ -1,25 +0,0 @@
|
||||
export function PlugIcon({
|
||||
className,
|
||||
fill,
|
||||
}: {
|
||||
className?: string;
|
||||
fill?: string;
|
||||
}) {
|
||||
return (
|
||||
<svg
|
||||
width="418"
|
||||
height="418"
|
||||
viewBox="0 0 418 418"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
className={className}
|
||||
fill={fill}
|
||||
>
|
||||
<path
|
||||
fill-rule="evenodd"
|
||||
clip-rule="evenodd"
|
||||
d="M411.662 6.12075C419.821 14.2794 419.821 27.5054 411.662 35.6637L390.942 56.3841C422.842 102.22 418.355 165.702 377.482 206.57L357.947 226.104C341.701 242.351 315.354 242.351 299.106 226.104L191.677 118.675C175.43 102.428 175.43 76.0848 191.677 59.8335L211.211 40.3029C252.084 -0.570291 315.56 -5.05725 361.397 26.8393L382.117 6.11896C390.276 -2.03965 403.502 -2.03965 411.66 6.11896L411.662 6.12075ZM347.939 69.8441C318.34 40.2456 270.35 40.2456 240.751 69.8441L221.342 89.2565L328.53 196.444L347.942 177.031C377.541 147.433 377.541 99.4426 347.942 69.8441H347.939ZM172.391 142.848C180.549 151.007 180.549 164.233 172.391 172.391L135.889 208.893L208.893 281.897L245.395 245.396C253.553 237.237 266.78 237.237 274.938 245.396C283.093 253.554 283.093 266.78 274.938 274.939L235.736 314.14C241.164 328.891 237.953 346.103 226.105 357.952L206.575 377.482C165.701 418.356 102.216 422.846 56.3797 390.946L35.6593 411.666C27.5007 419.821 14.2747 419.821 6.11634 411.666C-2.03878 403.508 -2.03878 390.282 6.11634 382.123L26.8367 361.403C-5.05987 315.567 -0.57291 252.085 40.3003 211.217L59.8309 191.683C71.6785 179.835 88.8913 176.629 103.642 182.056L142.848 142.85C151.003 134.695 164.229 134.695 172.387 142.85L172.391 142.848ZM89.2557 221.343L69.8468 240.756C40.2483 270.354 40.2483 318.345 69.8468 347.943C99.4426 377.545 147.432 377.545 177.034 347.943L196.447 328.534L89.2557 221.343Z"
|
||||
fill={fill}
|
||||
/>
|
||||
</svg>
|
||||
);
|
||||
}
|
||||
@@ -1,32 +1,24 @@
|
||||
import classNames from "classnames";
|
||||
import * as React from "react";
|
||||
import { cn } from "~/utils/cn";
|
||||
|
||||
const roundedStyles = {
|
||||
roundedLeft: "rounded-l -mr-1",
|
||||
roundedRight: "rounded-r -ml-1",
|
||||
roundedFull: "rounded",
|
||||
};
|
||||
export interface InputProps
|
||||
extends React.InputHTMLAttributes<HTMLInputElement> {}
|
||||
|
||||
type InputProps = JSX.IntrinsicElements["input"] & {
|
||||
roundedEdges?: "roundedLeft" | "roundedRight" | "roundedFull";
|
||||
};
|
||||
const Input = React.forwardRef<HTMLInputElement, InputProps>(
|
||||
({ className, type, ...props }, ref) => {
|
||||
return (
|
||||
<input
|
||||
type={type}
|
||||
className={cn(
|
||||
"flex h-10 w-full rounded-md border border-input bg-transparent px-3 py-2 text-sm ring-offset-background file:border-0 file:bg-transparent file:text-sm file:font-medium placeholder:text-muted-foreground focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 disabled:cursor-not-allowed disabled:opacity-50",
|
||||
className
|
||||
)}
|
||||
ref={ref}
|
||||
{...props}
|
||||
/>
|
||||
);
|
||||
}
|
||||
);
|
||||
Input.displayName = "Input";
|
||||
|
||||
export function Input({
|
||||
children,
|
||||
className,
|
||||
roundedEdges = "roundedFull",
|
||||
...props
|
||||
}: InputProps) {
|
||||
const classes = classNames(roundedStyles[roundedEdges], className);
|
||||
|
||||
return (
|
||||
<input
|
||||
{...props}
|
||||
className={classNames(
|
||||
`flex grow py-2 pl-4 pr-1 text-slate-200 rounded border-none bg-black/20 group-focus:border-indigo-500 placeholder:text-slate-600 focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-indigo-500`,
|
||||
classes
|
||||
)}
|
||||
>
|
||||
{children}
|
||||
</input>
|
||||
);
|
||||
}
|
||||
export { Input };
|
||||
|
||||
@@ -1,24 +1,13 @@
|
||||
import classNames from "classnames";
|
||||
import { cn } from "~/utils/cn";
|
||||
|
||||
type InputGroupProps = {
|
||||
layout?: "vertical" | "horizontal";
|
||||
children: React.ReactNode;
|
||||
className?: string;
|
||||
};
|
||||
|
||||
export function InputGroup({
|
||||
layout = "vertical",
|
||||
children,
|
||||
className,
|
||||
}: InputGroupProps) {
|
||||
export function InputGroup({ children, className }: InputGroupProps) {
|
||||
return (
|
||||
<div
|
||||
className={classNames(
|
||||
"mb-2 grid gap-1",
|
||||
{ className },
|
||||
layout === "horizontal" ? "grid-cols-2" : "grid-cols-1"
|
||||
)}
|
||||
>
|
||||
<div className={cn("grid w-full max-w-sm items-center gap-1.5", className)}>
|
||||
{children}
|
||||
</div>
|
||||
);
|
||||
|
||||
@@ -0,0 +1,3 @@
|
||||
export function InputHint({ children }: { children: React.ReactNode }) {
|
||||
return <p className="slate-400 text-xs">{children}</p>;
|
||||
}
|
||||
@@ -1,15 +1,26 @@
|
||||
import classNames from "classnames";
|
||||
"use client";
|
||||
|
||||
type LabelProps = React.DetailedHTMLProps<
|
||||
React.LabelHTMLAttributes<HTMLLabelElement>,
|
||||
HTMLLabelElement
|
||||
>;
|
||||
import * as LabelPrimitive from "@radix-ui/react-label";
|
||||
import type { VariantProps } from "class-variance-authority";
|
||||
import { cva } from "class-variance-authority";
|
||||
import * as React from "react";
|
||||
import { cn } from "~/utils/cn";
|
||||
|
||||
export function Label(props: LabelProps) {
|
||||
return (
|
||||
<label
|
||||
className={classNames("text-sm text-slate-500", props.className)}
|
||||
{...props}
|
||||
/>
|
||||
);
|
||||
}
|
||||
const labelVariants = cva(
|
||||
"text-sm font-medium leading-none peer-disabled:cursor-not-allowed peer-disabled:opacity-70"
|
||||
);
|
||||
|
||||
const Label = React.forwardRef<
|
||||
React.ElementRef<typeof LabelPrimitive.Root>,
|
||||
React.ComponentPropsWithoutRef<typeof LabelPrimitive.Root> &
|
||||
VariantProps<typeof labelVariants>
|
||||
>(({ className, ...props }, ref) => (
|
||||
<LabelPrimitive.Root
|
||||
ref={ref}
|
||||
className={cn(labelVariants(), className)}
|
||||
{...props}
|
||||
/>
|
||||
));
|
||||
Label.displayName = LabelPrimitive.Root.displayName;
|
||||
|
||||
export { Label };
|
||||
|
||||
@@ -1,72 +0,0 @@
|
||||
import { Listbox } from "@headlessui/react";
|
||||
import { ChevronUpDownIcon } from "@heroicons/react/24/outline";
|
||||
import classNames from "classnames";
|
||||
|
||||
type LabelProps = Parameters<typeof Listbox.Label>[0];
|
||||
const labelClassName = "block text-sm font-medium text-gray-700";
|
||||
function Label(props: LabelProps) {
|
||||
return (
|
||||
<Listbox className={classNames(labelClassName, props.className)} {...props}>
|
||||
{props.children}
|
||||
</Listbox>
|
||||
);
|
||||
}
|
||||
|
||||
type ButtonProps = Parameters<typeof Listbox.Button>[0] & {
|
||||
children: React.ReactNode;
|
||||
};
|
||||
|
||||
const buttonClassName =
|
||||
"relative w-full rounded bg-slate-700 py-2 pl-4 pr-10 text-slate-300 text-sm text-left shadow-md hover:cursor-pointer hover:bg-slate-600/80 transition";
|
||||
function Button({ children, ...props }: ButtonProps) {
|
||||
return (
|
||||
<Listbox.Button
|
||||
className={classNames(buttonClassName, props.className)}
|
||||
{...props}
|
||||
>
|
||||
<span className="block truncate">{children}</span>
|
||||
<span className="pointer-events-none absolute inset-y-0 right-0 flex items-center pr-2">
|
||||
<ChevronUpDownIcon
|
||||
className="h-5 w-5 text-gray-400"
|
||||
aria-hidden="true"
|
||||
/>
|
||||
</span>
|
||||
</Listbox.Button>
|
||||
);
|
||||
}
|
||||
|
||||
type OptionsProps = Parameters<typeof Listbox.Options>[0];
|
||||
const optionsClassName =
|
||||
"absolute z-10 mt-1 max-h-96 w-full overflow-auto rounded p-1 bg-slate-700 text-base shadow-lg";
|
||||
function Options(props: OptionsProps) {
|
||||
return (
|
||||
<Listbox.Options
|
||||
className={classNames(optionsClassName, props.className)}
|
||||
{...props}
|
||||
>
|
||||
{props.children}
|
||||
</Listbox.Options>
|
||||
);
|
||||
}
|
||||
|
||||
type OptionProps = Parameters<typeof Listbox.Option>[0];
|
||||
const optionClassName = "relative cursor-default select-none py-2 pl-3 pr-7";
|
||||
const activeOptionClassName =
|
||||
"bg-slate-800 rounded hover:cursor-pointer font-bold";
|
||||
const inactiveOptionClassName = "text-slate-300";
|
||||
function Option(props: OptionProps) {
|
||||
return (
|
||||
<Listbox.Option
|
||||
className={({ active }: { active: boolean }) =>
|
||||
classNames(
|
||||
active ? activeOptionClassName : inactiveOptionClassName,
|
||||
optionClassName,
|
||||
props.className
|
||||
)
|
||||
}
|
||||
{...props}
|
||||
/>
|
||||
);
|
||||
}
|
||||
|
||||
export const StyledListBox = { Label, Button, Options, Option };
|
||||
@@ -1,19 +0,0 @@
|
||||
import React, { memo } from "react";
|
||||
|
||||
export type TooltipProps = {
|
||||
children: React.ReactNode;
|
||||
text: string;
|
||||
};
|
||||
|
||||
export const MenuTitleToolTip: React.FC<TooltipProps> = memo((props) => {
|
||||
return (
|
||||
<span className="group relative flex">
|
||||
<span className="pointer-events-none absolute top-0.5 left-12 flex translate-x-0 items-center justify-center whitespace-nowrap rounded bg-slate-700 px-3 py-2 text-sm text-slate-300 opacity-0 shadow transition before:absolute before:-left-2 before:top-full before:-translate-y-[22px] before:border-4 before:border-transparent before:border-r-slate-700 before:shadow before:content-[''] group-hover:opacity-100">
|
||||
{props.text}
|
||||
</span>
|
||||
{props.children}
|
||||
</span>
|
||||
);
|
||||
});
|
||||
|
||||
MenuTitleToolTip.displayName = "Menu Title";
|
||||
@@ -1,77 +0,0 @@
|
||||
import { Link } from "@remix-run/react";
|
||||
import classnames from "classnames";
|
||||
|
||||
type NavLinkProps = Parameters<typeof Link>[0];
|
||||
|
||||
export function NavLink({
|
||||
to,
|
||||
children,
|
||||
target,
|
||||
className,
|
||||
onClick,
|
||||
...props
|
||||
}: NavLinkProps) {
|
||||
return (
|
||||
<Link
|
||||
to={to}
|
||||
{...props}
|
||||
onClick={onClick}
|
||||
target={target}
|
||||
className={classnames(
|
||||
"hover:text-toxic-500 inline-block whitespace-nowrap py-1 text-sm text-slate-200 transition md:px-2",
|
||||
{ className }
|
||||
)}
|
||||
>
|
||||
{children}
|
||||
</Link>
|
||||
);
|
||||
}
|
||||
|
||||
export function MobileNavLink({
|
||||
to,
|
||||
children,
|
||||
className,
|
||||
onClick,
|
||||
...props
|
||||
}: NavLinkProps) {
|
||||
return (
|
||||
<Link
|
||||
to={to}
|
||||
{...props}
|
||||
onClick={onClick}
|
||||
className={classnames(
|
||||
"hover:text-toxic-500 text-s block w-full whitespace-nowrap rounded-lg bg-slate-900 p-2 text-center text-sm text-slate-50 transition",
|
||||
{ className }
|
||||
)}
|
||||
>
|
||||
{children}
|
||||
</Link>
|
||||
);
|
||||
}
|
||||
|
||||
export function MobileNavIcon({ open }: { open: boolean }) {
|
||||
return (
|
||||
<svg
|
||||
aria-hidden="true"
|
||||
className="h-3.5 w-3.5 overflow-visible stroke-slate-300"
|
||||
fill="none"
|
||||
strokeWidth={2}
|
||||
strokeLinecap="round"
|
||||
>
|
||||
<path
|
||||
d="M0 1H14M0 7H14M0 13H14"
|
||||
className={classnames(
|
||||
"origin-center transition",
|
||||
open && "scale-90 opacity-0"
|
||||
)}
|
||||
/>
|
||||
<path
|
||||
d="M2 2L12 12M12 2L2 12"
|
||||
className={classnames(
|
||||
"origin-center transition",
|
||||
!open && "scale-90 opacity-0"
|
||||
)}
|
||||
/>
|
||||
</svg>
|
||||
);
|
||||
}
|
||||
@@ -1,17 +1,119 @@
|
||||
import classNames from "classnames";
|
||||
"use client";
|
||||
|
||||
type SelectProps = React.DetailedHTMLProps<
|
||||
React.SelectHTMLAttributes<HTMLSelectElement>,
|
||||
HTMLSelectElement
|
||||
>;
|
||||
import * as React from "react";
|
||||
import * as SelectPrimitive from "@radix-ui/react-select";
|
||||
import { Check, ChevronDown } from "lucide-react";
|
||||
import { cn } from "~/utils/cn";
|
||||
|
||||
const defaultClasses =
|
||||
"block rounded bg-slate-700 text-slate-200 shadow-md border-none py-2 pl-4 pr-9 text-sm hover:cursor-pointer hover:bg-slate-700/50 focus:border-none focus:outline-none focus:ring-0 transition";
|
||||
const Select = SelectPrimitive.Root;
|
||||
|
||||
export function Select({ children, className, ...props }: SelectProps) {
|
||||
return (
|
||||
<select className={classNames(defaultClasses, className)} {...props}>
|
||||
{children}
|
||||
</select>
|
||||
);
|
||||
}
|
||||
const SelectGroup = SelectPrimitive.Group;
|
||||
|
||||
const SelectValue = SelectPrimitive.Value;
|
||||
|
||||
const SelectTrigger = React.forwardRef<
|
||||
React.ElementRef<typeof SelectPrimitive.Trigger>,
|
||||
React.ComponentPropsWithoutRef<typeof SelectPrimitive.Trigger>
|
||||
>(({ className, children, ...props }, ref) => (
|
||||
<SelectPrimitive.Trigger
|
||||
ref={ref}
|
||||
className={cn(
|
||||
"flex h-10 w-full items-center justify-between rounded-md border border-input bg-transparent px-3 py-2 text-sm ring-offset-background placeholder:text-muted-foreground focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 disabled:cursor-not-allowed disabled:opacity-50",
|
||||
className
|
||||
)}
|
||||
{...props}
|
||||
>
|
||||
{children}
|
||||
<SelectPrimitive.Icon asChild>
|
||||
<ChevronDown className="h-4 w-4 opacity-50" />
|
||||
</SelectPrimitive.Icon>
|
||||
</SelectPrimitive.Trigger>
|
||||
));
|
||||
SelectTrigger.displayName = SelectPrimitive.Trigger.displayName;
|
||||
|
||||
const SelectContent = React.forwardRef<
|
||||
React.ElementRef<typeof SelectPrimitive.Content>,
|
||||
React.ComponentPropsWithoutRef<typeof SelectPrimitive.Content>
|
||||
>(({ className, children, position = "popper", ...props }, ref) => (
|
||||
<SelectPrimitive.Portal>
|
||||
<SelectPrimitive.Content
|
||||
ref={ref}
|
||||
className={cn(
|
||||
"relative z-50 min-w-[8rem] overflow-hidden rounded-md border bg-popover text-popover-foreground shadow-md animate-in fade-in-80",
|
||||
position === "popper" && "translate-y-1",
|
||||
className
|
||||
)}
|
||||
position={position}
|
||||
{...props}
|
||||
>
|
||||
<SelectPrimitive.Viewport
|
||||
className={cn(
|
||||
"p-1",
|
||||
position === "popper" &&
|
||||
"h-[var(--radix-select-trigger-height)] w-full min-w-[var(--radix-select-trigger-width)]"
|
||||
)}
|
||||
>
|
||||
{children}
|
||||
</SelectPrimitive.Viewport>
|
||||
</SelectPrimitive.Content>
|
||||
</SelectPrimitive.Portal>
|
||||
));
|
||||
SelectContent.displayName = SelectPrimitive.Content.displayName;
|
||||
|
||||
const SelectLabel = React.forwardRef<
|
||||
React.ElementRef<typeof SelectPrimitive.Label>,
|
||||
React.ComponentPropsWithoutRef<typeof SelectPrimitive.Label>
|
||||
>(({ className, ...props }, ref) => (
|
||||
<SelectPrimitive.Label
|
||||
ref={ref}
|
||||
className={cn("py-1.5 pl-8 pr-2 text-sm font-semibold", className)}
|
||||
{...props}
|
||||
/>
|
||||
));
|
||||
SelectLabel.displayName = SelectPrimitive.Label.displayName;
|
||||
|
||||
const SelectItem = React.forwardRef<
|
||||
React.ElementRef<typeof SelectPrimitive.Item>,
|
||||
React.ComponentPropsWithoutRef<typeof SelectPrimitive.Item>
|
||||
>(({ className, children, ...props }, ref) => (
|
||||
<SelectPrimitive.Item
|
||||
ref={ref}
|
||||
className={cn(
|
||||
"data-[disabled]:pointer-events-none data-[disabled]:opacity-50 relative flex w-full cursor-default select-none items-center rounded-sm py-1.5 pl-8 pr-2 text-sm outline-none focus:bg-accent focus:text-accent-foreground",
|
||||
className
|
||||
)}
|
||||
{...props}
|
||||
>
|
||||
<span className="absolute left-2 flex h-3.5 w-3.5 items-center justify-center">
|
||||
<SelectPrimitive.ItemIndicator>
|
||||
<Check className="h-4 w-4" />
|
||||
</SelectPrimitive.ItemIndicator>
|
||||
</span>
|
||||
|
||||
<SelectPrimitive.ItemText>{children}</SelectPrimitive.ItemText>
|
||||
</SelectPrimitive.Item>
|
||||
));
|
||||
SelectItem.displayName = SelectPrimitive.Item.displayName;
|
||||
|
||||
const SelectSeparator = React.forwardRef<
|
||||
React.ElementRef<typeof SelectPrimitive.Separator>,
|
||||
React.ComponentPropsWithoutRef<typeof SelectPrimitive.Separator>
|
||||
>(({ className, ...props }, ref) => (
|
||||
<SelectPrimitive.Separator
|
||||
ref={ref}
|
||||
className={cn("-mx-1 my-1 h-px bg-muted", className)}
|
||||
{...props}
|
||||
/>
|
||||
));
|
||||
SelectSeparator.displayName = SelectPrimitive.Separator.displayName;
|
||||
|
||||
export {
|
||||
Select,
|
||||
SelectGroup,
|
||||
SelectValue,
|
||||
SelectTrigger,
|
||||
SelectContent,
|
||||
SelectLabel,
|
||||
SelectItem,
|
||||
SelectSeparator,
|
||||
};
|
||||
|
||||
@@ -1,14 +1,12 @@
|
||||
export * from "./Buttons";
|
||||
export * from "./Dialog";
|
||||
export * from "./FormError";
|
||||
export * from "./IconPlug";
|
||||
export * from "./Input";
|
||||
export * from "./InputGroup";
|
||||
export * from "./Label";
|
||||
export * from "./ListBox";
|
||||
export * from "./MenuTitleToolTip";
|
||||
export * from "./NavLink";
|
||||
export * from "./InputHint";
|
||||
export * from "./PrettyDuration";
|
||||
export * from "./Select";
|
||||
export * from "./Sheet";
|
||||
export * from "./Spinner";
|
||||
export * from "./Tabs";
|
||||
|
||||
+7
-8
@@ -1,24 +1,23 @@
|
||||
import type { Meta, StoryObj } from "@storybook/react";
|
||||
import { withDesign } from "storybook-addon-designs";
|
||||
import { Button } from "../Buttons";
|
||||
|
||||
import { DangerButton } from "../primitives/Buttons";
|
||||
|
||||
const meta: Meta<typeof DangerButton> = {
|
||||
title: "Primitives/DangerButton",
|
||||
component: DangerButton,
|
||||
const meta: Meta<typeof Button> = {
|
||||
title: "Primitives/Button",
|
||||
component: Button,
|
||||
decorators: [withDesign],
|
||||
};
|
||||
|
||||
export default meta;
|
||||
|
||||
type Story = StoryObj<typeof DangerButton>;
|
||||
type Story = StoryObj<typeof Button>;
|
||||
|
||||
export const Basic: Story = {
|
||||
args: {
|
||||
children: "Danger Button",
|
||||
text: "Action text",
|
||||
},
|
||||
|
||||
render: (args) => <DangerButton {...args} />,
|
||||
render: (args) => <Button {...args} />,
|
||||
};
|
||||
|
||||
Basic.parameters = {
|
||||
+1
-1
@@ -1,7 +1,7 @@
|
||||
import type { Meta, StoryObj } from "@storybook/react";
|
||||
import { withDesign } from "storybook-addon-designs";
|
||||
|
||||
import { StyledDialog } from "../primitives/Dialog";
|
||||
import { StyledDialog } from "../Dialog";
|
||||
|
||||
const meta: Meta<typeof StyledDialog> = {
|
||||
title: "Primitives/Dialog",
|
||||
+15
-4
@@ -1,7 +1,13 @@
|
||||
import type { Meta, StoryObj } from "@storybook/react";
|
||||
import { withDesign } from "storybook-addon-designs";
|
||||
|
||||
import { Select } from "../primitives/Select";
|
||||
import {
|
||||
Select,
|
||||
SelectContent,
|
||||
SelectItem,
|
||||
SelectTrigger,
|
||||
SelectValue,
|
||||
} from "../Select";
|
||||
|
||||
const meta: Meta<typeof Select> = {
|
||||
title: "Primitives/Select",
|
||||
@@ -19,9 +25,14 @@ export const Basic: Story = {
|
||||
},
|
||||
render: (args) => (
|
||||
<Select>
|
||||
<option>Option One</option>
|
||||
<option>Option Two </option>
|
||||
<option>Option Three</option>
|
||||
<SelectTrigger className="w-[180px]">
|
||||
<SelectValue placeholder="Theme" />
|
||||
</SelectTrigger>
|
||||
<SelectContent>
|
||||
<SelectItem value="light">Light</SelectItem>
|
||||
<SelectItem value="dark">Dark</SelectItem>
|
||||
<SelectItem value="system">System</SelectItem>
|
||||
</SelectContent>
|
||||
</Select>
|
||||
),
|
||||
};
|
||||
@@ -1,30 +0,0 @@
|
||||
export type BodyProps = {
|
||||
children: React.ReactNode;
|
||||
size?: Size;
|
||||
className?: string;
|
||||
};
|
||||
|
||||
type Size = "regular" | "small" | "extra-small";
|
||||
|
||||
const baseClasses = "font-sans";
|
||||
const overrideClasses = "text-slate-300";
|
||||
|
||||
export function Body({
|
||||
children,
|
||||
className = overrideClasses,
|
||||
size = "regular",
|
||||
}: BodyProps) {
|
||||
let sizeClass = "text-base";
|
||||
switch (size) {
|
||||
case "small":
|
||||
sizeClass = "text-sm";
|
||||
break;
|
||||
case "extra-small":
|
||||
sizeClass = "text-xs";
|
||||
break;
|
||||
}
|
||||
|
||||
return (
|
||||
<p className={`${baseClasses} ${sizeClass} ${className}`}>{children}</p>
|
||||
);
|
||||
}
|
||||
@@ -1,82 +0,0 @@
|
||||
export type TitleProps = {
|
||||
children: React.ReactNode;
|
||||
size?: Size;
|
||||
className?: string;
|
||||
};
|
||||
|
||||
type Size =
|
||||
| "extra-extra-small"
|
||||
| "extra-small"
|
||||
| "small"
|
||||
| "regular"
|
||||
| "large"
|
||||
| "extra-large";
|
||||
|
||||
const baseClasses = "font-sans";
|
||||
const overrideClasses = "text-slate-200";
|
||||
|
||||
export function Header1({
|
||||
children,
|
||||
className = overrideClasses,
|
||||
size = "extra-large",
|
||||
}: TitleProps) {
|
||||
return (
|
||||
<h1 className={`${baseClasses} ${getSizeClassName(size)} ${className}`}>
|
||||
{children}
|
||||
</h1>
|
||||
);
|
||||
}
|
||||
|
||||
export function Header2({
|
||||
children,
|
||||
className = overrideClasses,
|
||||
size = "large",
|
||||
}: TitleProps) {
|
||||
return (
|
||||
<h2 className={`${baseClasses} ${getSizeClassName(size)} ${className}`}>
|
||||
{children}
|
||||
</h2>
|
||||
);
|
||||
}
|
||||
|
||||
export function Header3({
|
||||
children,
|
||||
className = overrideClasses,
|
||||
size = "regular",
|
||||
}: TitleProps) {
|
||||
return (
|
||||
<h3 className={`${baseClasses} ${getSizeClassName(size)} ${className}`}>
|
||||
{children}
|
||||
</h3>
|
||||
);
|
||||
}
|
||||
|
||||
export function Header4({
|
||||
children,
|
||||
className = overrideClasses,
|
||||
size = "small",
|
||||
}: TitleProps) {
|
||||
return (
|
||||
<h4 className={`${baseClasses} ${getSizeClassName(size)} ${className}`}>
|
||||
{children}
|
||||
</h4>
|
||||
);
|
||||
}
|
||||
|
||||
function getSizeClassName(size: Size) {
|
||||
switch (size) {
|
||||
case "extra-extra-small":
|
||||
return "text-sm";
|
||||
case "extra-small":
|
||||
return "text-base";
|
||||
case "small":
|
||||
return "text-lg";
|
||||
case "large":
|
||||
return "text-2xl";
|
||||
case "extra-large":
|
||||
return "text-3xl";
|
||||
case "regular":
|
||||
default:
|
||||
return "text-xl";
|
||||
}
|
||||
}
|
||||
@@ -1,15 +0,0 @@
|
||||
import { Header2 } from "./Headers";
|
||||
|
||||
export function SubTitle({
|
||||
children,
|
||||
className,
|
||||
}: {
|
||||
children: React.ReactNode;
|
||||
className?: string;
|
||||
}) {
|
||||
return (
|
||||
<Header2 size="small" className={`mb-2 text-slate-400 ${className}`}>
|
||||
{children}
|
||||
</Header2>
|
||||
);
|
||||
}
|
||||
@@ -1,16 +0,0 @@
|
||||
import classNames from "classnames";
|
||||
import { Header1 } from "./Headers";
|
||||
|
||||
export function Title({
|
||||
children,
|
||||
className,
|
||||
}: {
|
||||
children: React.ReactNode;
|
||||
className?: string;
|
||||
}) {
|
||||
return (
|
||||
<Header1 size="extra-large" className={classNames("mb-6 text-slate-200")}>
|
||||
{children}
|
||||
</Header1>
|
||||
);
|
||||
}
|
||||
@@ -1,28 +0,0 @@
|
||||
import type { Meta, StoryObj } from "@storybook/react";
|
||||
import { withDesign } from "storybook-addon-designs";
|
||||
|
||||
import { PrimaryButton } from "../primitives/Buttons";
|
||||
|
||||
const meta: Meta<typeof PrimaryButton> = {
|
||||
title: "Primitives/PrimaryButton",
|
||||
component: PrimaryButton,
|
||||
decorators: [withDesign],
|
||||
};
|
||||
|
||||
export default meta;
|
||||
|
||||
type Story = StoryObj<typeof PrimaryButton>;
|
||||
|
||||
export const Basic: Story = {
|
||||
args: {
|
||||
children: "Primary Button",
|
||||
},
|
||||
render: (args) => <PrimaryButton {...args} />,
|
||||
};
|
||||
|
||||
Basic.parameters = {
|
||||
design: {
|
||||
type: "figma",
|
||||
url: "https://www.figma.com/file/LKQ4FJ4bTnCSjedbRpk931/Sample-File",
|
||||
},
|
||||
};
|
||||
@@ -1,28 +0,0 @@
|
||||
import type { Meta, StoryObj } from "@storybook/react";
|
||||
import { withDesign } from "storybook-addon-designs";
|
||||
|
||||
import { SecondaryButton } from "../primitives/Buttons";
|
||||
|
||||
const meta: Meta<typeof SecondaryButton> = {
|
||||
title: "Primitives/SecondaryButton",
|
||||
component: SecondaryButton,
|
||||
decorators: [withDesign],
|
||||
};
|
||||
|
||||
export default meta;
|
||||
|
||||
type Story = StoryObj<typeof SecondaryButton>;
|
||||
|
||||
export const Basic: Story = {
|
||||
args: {
|
||||
children: "Secondary Button",
|
||||
},
|
||||
render: (args) => <SecondaryButton {...args} />,
|
||||
};
|
||||
|
||||
Basic.parameters = {
|
||||
design: {
|
||||
type: "figma",
|
||||
url: "https://www.figma.com/file/LKQ4FJ4bTnCSjedbRpk931/Sample-File",
|
||||
},
|
||||
};
|
||||
@@ -1,28 +0,0 @@
|
||||
import type { Meta, StoryObj } from "@storybook/react";
|
||||
import { withDesign } from "storybook-addon-designs";
|
||||
|
||||
import { TertiaryButton } from "../primitives/Buttons";
|
||||
|
||||
const meta: Meta<typeof TertiaryButton> = {
|
||||
title: "Primitives/TertiaryButton",
|
||||
component: TertiaryButton,
|
||||
decorators: [withDesign],
|
||||
};
|
||||
|
||||
export default meta;
|
||||
|
||||
type Story = StoryObj<typeof TertiaryButton>;
|
||||
|
||||
export const Basic: Story = {
|
||||
args: {
|
||||
children: "Tertiary Button",
|
||||
},
|
||||
render: (args) => <TertiaryButton {...args} />,
|
||||
};
|
||||
|
||||
Basic.parameters = {
|
||||
design: {
|
||||
type: "figma",
|
||||
url: "https://www.figma.com/file/LKQ4FJ4bTnCSjedbRpk931/Sample-File",
|
||||
},
|
||||
};
|
||||
@@ -2,7 +2,7 @@ import classNames from "classnames";
|
||||
import type { TemplateListItem } from "~/presenters/templateListPresenter.server";
|
||||
import { ApiLogoIcon } from "../code/ApiLogoIcon";
|
||||
import { Body } from "../primitives/text/Body";
|
||||
import { Header1 } from "../primitives/text/Headers";
|
||||
import { Header1 } from "../primitives/Headers";
|
||||
|
||||
export function TemplateCard({
|
||||
template,
|
||||
|
||||
@@ -6,7 +6,7 @@ import { ApiLogoIcon } from "../code/ApiLogoIcon";
|
||||
import { CopyTextPanel } from "../CopyTextButton";
|
||||
import { SecondaryA } from "../primitives/Buttons";
|
||||
import { Body } from "../primitives/text/Body";
|
||||
import { Header1 } from "../primitives/text/Headers";
|
||||
import { Header1 } from "../primitives/Headers";
|
||||
|
||||
export function TemplateOverview({
|
||||
template,
|
||||
|
||||
@@ -5,7 +5,7 @@ import { Fragment, useState } from "react";
|
||||
import type { TemplateListItem } from "~/presenters/templateListPresenter.server";
|
||||
import { CopyTextPanel } from "../CopyTextButton";
|
||||
import { StyledDialog } from "../primitives/Dialog";
|
||||
import { Header1 } from "../primitives/text/Headers";
|
||||
import { Header1 } from "../primitives/Headers";
|
||||
import { TemplateOverview } from "./TemplateOverview";
|
||||
|
||||
export function TemplatesGrid({
|
||||
|
||||
@@ -8,7 +8,7 @@ import type {
|
||||
WebhookEventTrigger,
|
||||
} from "@trigger.dev/internal";
|
||||
import { Body } from "../primitives/text/Body";
|
||||
import { Header2 } from "../primitives/text/Headers";
|
||||
import { Header2 } from "../primitives/Headers";
|
||||
import cronstrue from "cronstrue";
|
||||
|
||||
export function TriggerBody({ trigger }: { trigger: TriggerMetadata }) {
|
||||
|
||||
+1
-1
@@ -1,4 +1,4 @@
|
||||
export function StepNumber({
|
||||
export function TutorialStep({
|
||||
stepNumber,
|
||||
drawLine,
|
||||
active = false,
|
||||
@@ -7,7 +7,7 @@ import { PlusIcon } from "@heroicons/react/24/solid";
|
||||
import { Link } from "@remix-run/react";
|
||||
import { Fragment } from "react";
|
||||
import invariant from "tiny-invariant";
|
||||
import { BreadcrumbDivider } from "~/components/layout/Header";
|
||||
import { BreadcrumbDivider } from "~/components/navigation/NavBar";
|
||||
import { useCurrentOrganization } from "~/hooks/useOrganizations";
|
||||
|
||||
const dimmedClassNames = "text-slate-500";
|
||||
|
||||
@@ -4,7 +4,7 @@ import type { UseDataFunctionReturn } from "remix-typedjson";
|
||||
import { typedjson, useTypedLoaderData } from "remix-typedjson";
|
||||
import invariant from "tiny-invariant";
|
||||
import { Container } from "~/components/layout/Container";
|
||||
import { Header } from "~/components/layout/Header";
|
||||
import { Header } from "~/components/navigation/NavBar";
|
||||
import {
|
||||
ProjectSideMenu,
|
||||
SideMenuContainer,
|
||||
|
||||
+1
-1
@@ -3,7 +3,7 @@ import type { LoaderArgs } from "@remix-run/server-runtime";
|
||||
import { typedjson, useTypedLoaderData } from "remix-typedjson";
|
||||
import { z } from "zod";
|
||||
import { SecondaryLink } from "~/components/primitives/Buttons";
|
||||
import { Header1 } from "~/components/primitives/text/Headers";
|
||||
import { Header1 } from "~/components/primitives/Headers";
|
||||
import { SubTitle } from "~/components/primitives/text/SubTitle";
|
||||
import { DeploymentBuildLogsPresenter } from "~/features/ee/projects/presenters/deploymentBuildLogsPresenter.server";
|
||||
import { LogOutput } from "../../../../components/LogOutput";
|
||||
|
||||
+1
-1
@@ -14,7 +14,7 @@ import {
|
||||
import { PrettyDuration } from "~/components/primitives/PrettyDuration";
|
||||
import { Spinner } from "~/components/primitives/Spinner";
|
||||
import { Body } from "~/components/primitives/text/Body";
|
||||
import { Header1 } from "~/components/primitives/text/Headers";
|
||||
import { Header1 } from "~/components/primitives/Headers";
|
||||
import { SubTitle } from "~/components/primitives/text/SubTitle";
|
||||
import { deploymentStatusTitle } from "~/features/ee/projects/components/deploymentStatus";
|
||||
import { DeploymentPresenter } from "~/features/ee/projects/presenters/deploymentPresenter.server";
|
||||
|
||||
@@ -8,7 +8,7 @@ import { PanelWarning } from "~/components/layout/PanelInfo";
|
||||
import { TertiaryLink } from "~/components/primitives/Buttons";
|
||||
import { Spinner } from "~/components/primitives/Spinner";
|
||||
import { Body } from "~/components/primitives/text/Body";
|
||||
import { Header1, Header4 } from "~/components/primitives/text/Headers";
|
||||
import { Header1, Header4 } from "~/components/primitives/Headers";
|
||||
import { SubTitle } from "~/components/primitives/text/SubTitle";
|
||||
import { useCurrentProject } from "../$projectP";
|
||||
import { LogOutput } from "../../../components/LogOutput";
|
||||
|
||||
@@ -13,7 +13,7 @@ import { InputGroup } from "~/components/primitives/InputGroup";
|
||||
import { Label } from "~/components/primitives/Label";
|
||||
import { Select } from "~/components/primitives/Select";
|
||||
import { Body } from "~/components/primitives/text/Body";
|
||||
import { Header1 } from "~/components/primitives/text/Headers";
|
||||
import { Header1 } from "~/components/primitives/Headers";
|
||||
import { SubTitle } from "~/components/primitives/text/SubTitle";
|
||||
import { useLiveEnvironment } from "~/hooks/useEnvironments";
|
||||
import {
|
||||
|
||||
@@ -1,10 +1,10 @@
|
||||
import { CloudIcon } from "@heroicons/react/24/outline";
|
||||
import { AppBody, AppLayoutTwoCol } from "~/components/layout/AppLayout";
|
||||
import { Container } from "~/components/layout/Container";
|
||||
import { Header } from "~/components/layout/Header";
|
||||
import { Header } from "~/components/navigation/NavBar";
|
||||
import { OrganizationsSideMenu } from "~/components/navigation/SideMenu";
|
||||
import { Body } from "~/components/primitives/text/Body";
|
||||
import { Header1 } from "~/components/primitives/text/Headers";
|
||||
import { Header1 } from "~/components/primitives/Headers";
|
||||
|
||||
export default function ComingSoonPage() {
|
||||
return (
|
||||
|
||||
@@ -21,14 +21,14 @@ import { OctoKitty } from "~/components/GitHubLoginButton";
|
||||
import { IntlDate } from "~/components/IntlDate";
|
||||
import { AppBody, AppLayoutTwoCol } from "~/components/layout/AppLayout";
|
||||
import { Container } from "~/components/layout/Container";
|
||||
import { Header } from "~/components/layout/Header";
|
||||
import { Header } from "~/components/navigation/NavBar";
|
||||
import { List } from "~/components/layout/List";
|
||||
import { Panel } from "~/components/layout/Panel";
|
||||
import { OrganizationsSideMenu } from "~/components/navigation/SideMenu";
|
||||
import { PrimaryLink } from "~/components/primitives/Buttons";
|
||||
import { Spinner } from "~/components/primitives/Spinner";
|
||||
import { Body } from "~/components/primitives/text/Body";
|
||||
import { Header2 } from "~/components/primitives/text/Headers";
|
||||
import { Header2 } from "~/components/primitives/Headers";
|
||||
import { SubTitle } from "~/components/primitives/text/SubTitle";
|
||||
import { Title } from "~/components/primitives/text/Title";
|
||||
import { requireUser } from "~/services/session.server";
|
||||
|
||||
@@ -30,7 +30,7 @@ import invariant from "tiny-invariant";
|
||||
import { OctoKitty } from "~/components/GitHubLoginButton";
|
||||
import { AppBody, AppLayoutTwoCol } from "~/components/layout/AppLayout";
|
||||
import { Container } from "~/components/layout/Container";
|
||||
import { Header } from "~/components/layout/Header";
|
||||
import { Header } from "~/components/navigation/NavBar";
|
||||
import { List } from "~/components/layout/List";
|
||||
import { Panel } from "~/components/layout/Panel";
|
||||
import { PanelWarning } from "~/components/layout/PanelWarning";
|
||||
@@ -43,7 +43,7 @@ import {
|
||||
import { StyledDialog } from "~/components/primitives/Dialog";
|
||||
import { Spinner } from "~/components/primitives/Spinner";
|
||||
import { Body } from "~/components/primitives/text/Body";
|
||||
import { Header4 } from "~/components/primitives/text/Headers";
|
||||
import { Header4 } from "~/components/primitives/Headers";
|
||||
import { SubTitle } from "~/components/primitives/text/SubTitle";
|
||||
import { Title } from "~/components/primitives/text/Title";
|
||||
import { Tooltip } from "~/components/primitives/Tooltip";
|
||||
|
||||
@@ -7,10 +7,10 @@ import {
|
||||
import { Link } from "@remix-run/react";
|
||||
import classNames from "classnames";
|
||||
import { AppBody } from "~/components/layout/AppLayout";
|
||||
import { Header } from "~/components/layout/Header";
|
||||
import { Header } from "~/components/navigation/NavBar";
|
||||
import { MenuTitleToolTip } from "~/components/primitives/MenuTitleToolTip";
|
||||
import { Body } from "~/components/primitives/text/Body";
|
||||
import { Header4 } from "~/components/primitives/text/Headers";
|
||||
import { Header4 } from "~/components/primitives/Headers";
|
||||
import type { MatchedOrganization } from "~/hooks/useOrganizations";
|
||||
import { useOrganizations } from "~/hooks/useOrganizations";
|
||||
import { useOptionalUser } from "~/hooks/useUser";
|
||||
|
||||
@@ -5,7 +5,7 @@ import invariant from "tiny-invariant";
|
||||
import { CopyTextPanel } from "~/components/CopyTextButton";
|
||||
import { AppBody, AppLayoutTwoCol } from "~/components/layout/AppLayout";
|
||||
import { Container } from "~/components/layout/Container";
|
||||
import { Header } from "~/components/layout/Header";
|
||||
import { Header } from "~/components/navigation/NavBar";
|
||||
import { Panel } from "~/components/layout/Panel";
|
||||
import { OrganizationsSideMenu } from "~/components/navigation/SideMenu";
|
||||
import { TertiaryButton } from "~/components/primitives/Buttons";
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import { AppBody, AppLayoutTwoCol } from "~/components/layout/AppLayout";
|
||||
import { Container } from "~/components/layout/Container";
|
||||
import { Header } from "~/components/layout/Header";
|
||||
import { Header } from "~/components/navigation/NavBar";
|
||||
import { OrganizationsSideMenu } from "~/components/navigation/SideMenu";
|
||||
import { Title } from "~/components/primitives/text/Title";
|
||||
import { useDevEnvironment } from "~/hooks/useEnvironments";
|
||||
|
||||
@@ -7,7 +7,7 @@ import { NamedIcon, NamedIconInBox } from "~/components/Icon";
|
||||
import { ConnectButton } from "~/components/integrations/ConnectButton";
|
||||
import { AppBody, AppLayoutTwoCol } from "~/components/layout/AppLayout";
|
||||
import { Container } from "~/components/layout/Container";
|
||||
import { Header } from "~/components/layout/Header";
|
||||
import { Header } from "~/components/navigation/NavBar";
|
||||
import { List } from "~/components/layout/List";
|
||||
import { OrganizationsSideMenu } from "~/components/navigation/SideMenu";
|
||||
import { Badge } from "~/components/primitives/Badge";
|
||||
@@ -21,7 +21,7 @@ import {
|
||||
PopoverTrigger,
|
||||
} from "~/components/primitives/Popover";
|
||||
import { Body } from "~/components/primitives/text/Body";
|
||||
import { Header3 } from "~/components/primitives/text/Headers";
|
||||
import { Header3 } from "~/components/primitives/Headers";
|
||||
import { SubTitle } from "~/components/primitives/text/SubTitle";
|
||||
import { Title } from "~/components/primitives/text/Title";
|
||||
import { useCurrentOrganization } from "~/hooks/useOrganizations";
|
||||
|
||||
@@ -1,12 +1,12 @@
|
||||
import { UserGroupIcon } from "@heroicons/react/24/outline";
|
||||
import { Container } from "~/components/layout/Container";
|
||||
import { Body } from "~/components/primitives/text/Body";
|
||||
import { Header1 } from "~/components/primitives/text/Headers";
|
||||
import { Header1 } from "~/components/primitives/Headers";
|
||||
export default function Members() {
|
||||
return (
|
||||
<Container>
|
||||
<main className="w-full h-full flex items-center justify-center">
|
||||
<div className="flex flex-col items-center gap-y-3.5 min-w-[400px] bg-slate-800 shadow-md border border-slate-800 rounded-md p-10">
|
||||
<main className="flex h-full w-full items-center justify-center">
|
||||
<div className="flex min-w-[400px] flex-col items-center gap-y-3.5 rounded-md border border-slate-800 bg-slate-800 p-10 shadow-md">
|
||||
<UserGroupIcon className="h-10 w-10 text-indigo-500" />
|
||||
<Header1 size="large" className="">
|
||||
Manage team members
|
||||
|
||||
@@ -3,9 +3,9 @@ import type { ActionFunction } from "@remix-run/node";
|
||||
import { json, redirect } from "@remix-run/node";
|
||||
import { Form, useActionData } from "@remix-run/react";
|
||||
import * as React from "react";
|
||||
import { Header } from "~/components/layout/Header";
|
||||
import { Header } from "~/components/navigation/NavBar";
|
||||
import { PrimaryButton, SecondaryLink } from "~/components/primitives/Buttons";
|
||||
import { Header1 } from "~/components/primitives/text/Headers";
|
||||
import { Header1 } from "~/components/primitives/Headers";
|
||||
import { createOrganization } from "~/models/organization.server";
|
||||
import { requireUserId } from "~/services/session.server";
|
||||
|
||||
|
||||
@@ -7,7 +7,7 @@ import {
|
||||
PublicAppBody,
|
||||
PublicAppLayout,
|
||||
} from "~/components/layout/AppLayout";
|
||||
import { Header } from "~/components/layout/Header";
|
||||
import { Header } from "~/components/navigation/NavBar";
|
||||
import { MarketingHeader } from "~/components/layout/MarketingHeader";
|
||||
import { getOrganizations } from "~/models/organization.server";
|
||||
import { getImpersonationId } from "~/services/impersonation.server";
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import { typedjson, useTypedLoaderData } from "remix-typedjson";
|
||||
import { Header2 } from "~/components/primitives/text/Headers";
|
||||
import { Header2 } from "~/components/primitives/Headers";
|
||||
import { TemplatesGrid } from "~/components/templates/TemplatesGrid";
|
||||
import { TemplateListPresenter } from "~/presenters/templateListPresenter.server";
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import { BookOpenIcon } from "@heroicons/react/24/solid";
|
||||
import { Link, Outlet } from "@remix-run/react";
|
||||
import { Header } from "~/components/layout/Header";
|
||||
import { Header } from "~/components/navigation/NavBar";
|
||||
|
||||
const pages = [
|
||||
{
|
||||
|
||||
@@ -67,7 +67,9 @@
|
||||
"@octokit/webhooks-methods": "^3.0.2",
|
||||
"@prisma/client": "^4.13.0",
|
||||
"@radix-ui/react-dialog": "^1.0.3",
|
||||
"@radix-ui/react-label": "^2.0.1",
|
||||
"@radix-ui/react-popover": "^1.0.5",
|
||||
"@radix-ui/react-select": "^1.2.1",
|
||||
"@react-email/head": "^0.0.2",
|
||||
"@remix-run/express": "v1.11.0",
|
||||
"@remix-run/node": "v1.11.0",
|
||||
@@ -81,7 +83,6 @@
|
||||
"@uiw/react-codemirror": "^4.13.2",
|
||||
"bcryptjs": "^2.4.3",
|
||||
"class-variance-authority": "^0.5.2",
|
||||
"classnames": "^2.3.1",
|
||||
"clsx": "^1.2.1",
|
||||
"compression": "^1.7.4",
|
||||
"cron-parser": "^4.7.1",
|
||||
|
||||
Generated
+101
-2
@@ -68,7 +68,9 @@ importers:
|
||||
'@octokit/webhooks-types': ^6.10.0
|
||||
'@prisma/client': ^4.13.0
|
||||
'@radix-ui/react-dialog': ^1.0.3
|
||||
'@radix-ui/react-label': ^2.0.1
|
||||
'@radix-ui/react-popover': ^1.0.5
|
||||
'@radix-ui/react-select': ^1.2.1
|
||||
'@react-email/head': ^0.0.2
|
||||
'@remix-run/dev': v1.11.0
|
||||
'@remix-run/eslint-config': v1.11.0
|
||||
@@ -130,7 +132,6 @@ importers:
|
||||
bcryptjs: ^2.4.3
|
||||
c8: ^7.11.3
|
||||
class-variance-authority: ^0.5.2
|
||||
classnames: ^2.3.1
|
||||
cli-ux: ^6.0.9
|
||||
clsx: ^1.2.1
|
||||
compression: ^1.7.4
|
||||
@@ -249,7 +250,9 @@ importers:
|
||||
'@octokit/webhooks-methods': 3.0.2
|
||||
'@prisma/client': 4.13.0_prisma@4.13.0
|
||||
'@radix-ui/react-dialog': 1.0.3_ib3m5ricvtkl2cll7qpr2f6lvq
|
||||
'@radix-ui/react-label': 2.0.1_biqbaboplfbrettd7655fr4n2y
|
||||
'@radix-ui/react-popover': 1.0.5_ib3m5ricvtkl2cll7qpr2f6lvq
|
||||
'@radix-ui/react-select': 1.2.1_ib3m5ricvtkl2cll7qpr2f6lvq
|
||||
'@react-email/head': 0.0.2
|
||||
'@remix-run/express': 1.11.0_cwk4saenierp7pa7l5cpbeswge
|
||||
'@remix-run/node': 1.11.0_biqbaboplfbrettd7655fr4n2y
|
||||
@@ -263,7 +266,6 @@ importers:
|
||||
'@uiw/react-codemirror': 4.19.5_aguurb4bmecpxzejz52amioxne
|
||||
bcryptjs: 2.4.3
|
||||
class-variance-authority: 0.5.2_typescript@4.9.4
|
||||
classnames: 2.3.2
|
||||
clsx: 1.2.1
|
||||
compression: 1.7.4
|
||||
cron-parser: 4.7.1
|
||||
@@ -6481,6 +6483,12 @@ packages:
|
||||
resolution: {integrity: sha512-HrniowHRZXHuGT9XRgoXEaP2gJLXM5RMoItaY2PkjvuZ+iHc0Zjbm/302MB8YsPdWozAPHHn+jpFEcEn71OgPw==}
|
||||
requiresBuild: true
|
||||
|
||||
/@radix-ui/number/1.0.0:
|
||||
resolution: {integrity: sha512-Ofwh/1HX69ZfJRiRBMTy7rgjAzHmwe4kW9C9Y99HTRUcYLUuVT0KESFj15rPjRgKJs20GPq8Bm5aEDJ8DuA3vA==}
|
||||
dependencies:
|
||||
'@babel/runtime': 7.20.7
|
||||
dev: false
|
||||
|
||||
/@radix-ui/primitive/1.0.0:
|
||||
resolution: {integrity: sha512-3e7rn8FDMin4CgeL7Z/49smCA3rFYY3Ha2rUQ7HRWFadS5iCRw08ZgVT1LaNTCNqgvrUiyczLflrVrF0SRQtNA==}
|
||||
dependencies:
|
||||
@@ -6499,6 +6507,21 @@ packages:
|
||||
react-dom: 18.2.0_react@18.2.0
|
||||
dev: false
|
||||
|
||||
/@radix-ui/react-collection/1.0.2_biqbaboplfbrettd7655fr4n2y:
|
||||
resolution: {integrity: sha512-s8WdQQ6wNXpaxdZ308KSr8fEWGrg4un8i4r/w7fhiS4ElRNjk5rRcl0/C6TANG2LvLOGIxtzo/jAg6Qf73TEBw==}
|
||||
peerDependencies:
|
||||
react: ^16.8 || ^17.0 || ^18.0
|
||||
react-dom: ^16.8 || ^17.0 || ^18.0
|
||||
dependencies:
|
||||
'@babel/runtime': 7.20.7
|
||||
'@radix-ui/react-compose-refs': 1.0.0_react@18.2.0
|
||||
'@radix-ui/react-context': 1.0.0_react@18.2.0
|
||||
'@radix-ui/react-primitive': 1.0.2_biqbaboplfbrettd7655fr4n2y
|
||||
'@radix-ui/react-slot': 1.0.1_react@18.2.0
|
||||
react: 18.2.0
|
||||
react-dom: 18.2.0_react@18.2.0
|
||||
dev: false
|
||||
|
||||
/@radix-ui/react-compose-refs/1.0.0_react@18.2.0:
|
||||
resolution: {integrity: sha512-0KaSv6sx787/hK3eF53iOkiSLwAGlFMx5lotrqD2pTjB18KbybKoEIgkNZTKC60YECDQTKGTRcDBILwZVqVKvA==}
|
||||
peerDependencies:
|
||||
@@ -6544,6 +6567,15 @@ packages:
|
||||
- '@types/react'
|
||||
dev: false
|
||||
|
||||
/@radix-ui/react-direction/1.0.0_react@18.2.0:
|
||||
resolution: {integrity: sha512-2HV05lGUgYcA6xgLQ4BKPDmtL+QbIZYH5fCOTAOOcJ5O0QbWS3i9lKaurLzliYUDhORI2Qr3pyjhJh44lKA3rQ==}
|
||||
peerDependencies:
|
||||
react: ^16.8 || ^17.0 || ^18.0
|
||||
dependencies:
|
||||
'@babel/runtime': 7.20.7
|
||||
react: 18.2.0
|
||||
dev: false
|
||||
|
||||
/@radix-ui/react-dismissable-layer/1.0.3_biqbaboplfbrettd7655fr4n2y:
|
||||
resolution: {integrity: sha512-nXZOvFjOuHS1ovumntGV7NNoLaEp9JEvTht3MBjP44NSW5hUKj/8OnfN3+8WmB+CEhN44XaGhpHoSsUIEl5P7Q==}
|
||||
peerDependencies:
|
||||
@@ -6593,6 +6625,18 @@ packages:
|
||||
react: 18.2.0
|
||||
dev: false
|
||||
|
||||
/@radix-ui/react-label/2.0.1_biqbaboplfbrettd7655fr4n2y:
|
||||
resolution: {integrity: sha512-qcfbS3B8hTYmEO44RNcXB6pegkxRsJIbdxTMu0PEX0Luv5O2DvTIwwVYxQfUwLpM88EL84QRPLOLgwUSApMsLQ==}
|
||||
peerDependencies:
|
||||
react: ^16.8 || ^17.0 || ^18.0
|
||||
react-dom: ^16.8 || ^17.0 || ^18.0
|
||||
dependencies:
|
||||
'@babel/runtime': 7.20.7
|
||||
'@radix-ui/react-primitive': 1.0.2_biqbaboplfbrettd7655fr4n2y
|
||||
react: 18.2.0
|
||||
react-dom: 18.2.0_react@18.2.0
|
||||
dev: false
|
||||
|
||||
/@radix-ui/react-popover/1.0.5_ib3m5ricvtkl2cll7qpr2f6lvq:
|
||||
resolution: {integrity: sha512-GRHZ8yD12MrN2NLobHPE8Rb5uHTxd9x372DE9PPNnBjpczAQHcZ5ne0KXG4xpf+RDdXSzdLv9ym6mYJCDTaUZg==}
|
||||
peerDependencies:
|
||||
@@ -6681,6 +6725,40 @@ packages:
|
||||
react-dom: 18.2.0_react@18.2.0
|
||||
dev: false
|
||||
|
||||
/@radix-ui/react-select/1.2.1_ib3m5ricvtkl2cll7qpr2f6lvq:
|
||||
resolution: {integrity: sha512-GULRMITaOHNj79BZvQs3iZO0+f2IgI8g5HDhMi7Bnc13t7IlG86NFtOCfTLme4PNZdEtU+no+oGgcl6IFiphpQ==}
|
||||
peerDependencies:
|
||||
react: ^16.8 || ^17.0 || ^18.0
|
||||
react-dom: ^16.8 || ^17.0 || ^18.0
|
||||
dependencies:
|
||||
'@babel/runtime': 7.20.7
|
||||
'@radix-ui/number': 1.0.0
|
||||
'@radix-ui/primitive': 1.0.0
|
||||
'@radix-ui/react-collection': 1.0.2_biqbaboplfbrettd7655fr4n2y
|
||||
'@radix-ui/react-compose-refs': 1.0.0_react@18.2.0
|
||||
'@radix-ui/react-context': 1.0.0_react@18.2.0
|
||||
'@radix-ui/react-direction': 1.0.0_react@18.2.0
|
||||
'@radix-ui/react-dismissable-layer': 1.0.3_biqbaboplfbrettd7655fr4n2y
|
||||
'@radix-ui/react-focus-guards': 1.0.0_react@18.2.0
|
||||
'@radix-ui/react-focus-scope': 1.0.2_biqbaboplfbrettd7655fr4n2y
|
||||
'@radix-ui/react-id': 1.0.0_react@18.2.0
|
||||
'@radix-ui/react-popper': 1.1.1_ib3m5ricvtkl2cll7qpr2f6lvq
|
||||
'@radix-ui/react-portal': 1.0.2_biqbaboplfbrettd7655fr4n2y
|
||||
'@radix-ui/react-primitive': 1.0.2_biqbaboplfbrettd7655fr4n2y
|
||||
'@radix-ui/react-slot': 1.0.1_react@18.2.0
|
||||
'@radix-ui/react-use-callback-ref': 1.0.0_react@18.2.0
|
||||
'@radix-ui/react-use-controllable-state': 1.0.0_react@18.2.0
|
||||
'@radix-ui/react-use-layout-effect': 1.0.0_react@18.2.0
|
||||
'@radix-ui/react-use-previous': 1.0.0_react@18.2.0
|
||||
'@radix-ui/react-visually-hidden': 1.0.2_biqbaboplfbrettd7655fr4n2y
|
||||
aria-hidden: 1.2.3
|
||||
react: 18.2.0
|
||||
react-dom: 18.2.0_react@18.2.0
|
||||
react-remove-scroll: 2.5.5_kzbn2opkn2327fwg5yzwzya5o4
|
||||
transitivePeerDependencies:
|
||||
- '@types/react'
|
||||
dev: false
|
||||
|
||||
/@radix-ui/react-slot/1.0.0_react@18.2.0:
|
||||
resolution: {integrity: sha512-3mrKauI/tWXo1Ll+gN5dHcxDPdm/Df1ufcDLCecn+pnCIVcdWE7CujXo8QaXOWRJyZyQWWbpB8eFwHzWXlv5mQ==}
|
||||
peerDependencies:
|
||||
@@ -6739,6 +6817,15 @@ packages:
|
||||
react: 18.2.0
|
||||
dev: false
|
||||
|
||||
/@radix-ui/react-use-previous/1.0.0_react@18.2.0:
|
||||
resolution: {integrity: sha512-RG2K8z/K7InnOKpq6YLDmT49HGjNmrK+fr82UCVKT2sW0GYfVnYp4wZWBooT/EYfQ5faA9uIjvsuMMhH61rheg==}
|
||||
peerDependencies:
|
||||
react: ^16.8 || ^17.0 || ^18.0
|
||||
dependencies:
|
||||
'@babel/runtime': 7.20.7
|
||||
react: 18.2.0
|
||||
dev: false
|
||||
|
||||
/@radix-ui/react-use-rect/1.0.0_react@18.2.0:
|
||||
resolution: {integrity: sha512-TB7pID8NRMEHxb/qQJpvSt3hQU4sqNPM1VCTjTRjEOa7cEop/QMuq8S6fb/5Tsz64kqSvB9WnwsDHtjnrM9qew==}
|
||||
peerDependencies:
|
||||
@@ -6759,6 +6846,18 @@ packages:
|
||||
react: 18.2.0
|
||||
dev: false
|
||||
|
||||
/@radix-ui/react-visually-hidden/1.0.2_biqbaboplfbrettd7655fr4n2y:
|
||||
resolution: {integrity: sha512-qirnJxtYn73HEk1rXL12/mXnu2rwsNHDID10th2JGtdK25T9wX+mxRmGt7iPSahw512GbZOc0syZX1nLQGoEOg==}
|
||||
peerDependencies:
|
||||
react: ^16.8 || ^17.0 || ^18.0
|
||||
react-dom: ^16.8 || ^17.0 || ^18.0
|
||||
dependencies:
|
||||
'@babel/runtime': 7.20.7
|
||||
'@radix-ui/react-primitive': 1.0.2_biqbaboplfbrettd7655fr4n2y
|
||||
react: 18.2.0
|
||||
react-dom: 18.2.0_react@18.2.0
|
||||
dev: false
|
||||
|
||||
/@radix-ui/rect/1.0.0:
|
||||
resolution: {integrity: sha512-d0O68AYy/9oeEy1DdC07bz1/ZXX+DqCskRd3i4JzLSTXwefzaepQrKjXC7aNM8lTHjFLDO0pDgaEiQ7jEk+HVg==}
|
||||
dependencies:
|
||||
|
||||
Reference in New Issue
Block a user