Skip to content

Commit

Permalink
Add missing components
Browse files Browse the repository at this point in the history
  • Loading branch information
MajorTom327 committed Sep 22, 2023
1 parent 121cf12 commit 959ded2
Show file tree
Hide file tree
Showing 7 changed files with 231 additions and 50 deletions.
59 changes: 9 additions & 50 deletions app/components/Input/InputTextArea.tsx
Original file line number Diff line number Diff line change
@@ -1,45 +1,19 @@
import classNames from "classnames";
import { Asterisk } from "lucide-react";
import React, { useId, useState } from "react";
import React, { useId } from "react";
import { useRemixFormContext } from "remix-hook-form";
import { PromptEnum } from "~/refs/prompts";

import useGpt from "~/hooks/useGpt";

import AiCompletionButton from "../AiCompletionButton";
import { Label } from "../ui/label";
import { Textarea } from "../ui/textarea";
import { InputProps } from "./Input";
import type { InputProps } from "./Input";

type Props = Omit<InputProps, "type"> & {
prompt?: PromptEnum;
} & React.HTMLProps<HTMLTextAreaElement>;
type Props = Omit<
InputProps,
"type"
> & {} & React.HTMLProps<HTMLTextAreaElement>;

export const InputTextArea: React.FC<Props> = ({
addon,
label,
prompt,
...props
}) => {
export const InputTextArea: React.FC<Props> = ({ addon, label, ...props }) => {
const id = useId();
const { register, setValue, getValues } = useRemixFormContext();
const { complete, completion } = useGpt(prompt);
const [showCompletion, setShowCompletion] = useState(false);

const handleAskCompletion = () => {
const value = getValues(props.name!);
complete(value);
setShowCompletion(true);
};

const handleAcceptCompletion = () => {
setValue(props.name!, completion);
setShowCompletion(false);
};

const handleRefuseCompletion = () => {
setShowCompletion(false);
};
const { register } = useRemixFormContext();

const textareaProps = {
id,
Expand All @@ -49,10 +23,6 @@ export const InputTextArea: React.FC<Props> = ({
...register(props.name!, {
required: props.required,
}),
className: classNames({
"bg-base-200/20 cursor-not-allowed text-neutral/70 border-none ring ring-accent/50 focus:outline-none":
showCompletion,
}),
};
return (
<>
Expand All @@ -66,18 +36,7 @@ export const InputTextArea: React.FC<Props> = ({
)}
</Label>

<div className="relative">
<Textarea {...textareaProps} />

{prompt && (
<AiCompletionButton
completion={completion}
onAskCompletion={handleAskCompletion}
onAccept={handleAcceptCompletion}
onRefuse={handleRefuseCompletion}
/>
)}
</div>
<Textarea {...textareaProps} />
</div>
</>
);
Expand Down
28 changes: 28 additions & 0 deletions app/components/ui/checkbox.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
import * as CheckboxPrimitive from "@radix-ui/react-checkbox";
import { Check } from "lucide-react";
import * as React from "react";

import { cn } from "~/lib/utils";

const Checkbox = React.forwardRef<
React.ElementRef<typeof CheckboxPrimitive.Root>,
React.ComponentPropsWithoutRef<typeof CheckboxPrimitive.Root>
>(({ className, ...props }, ref) => (
<CheckboxPrimitive.Root
ref={ref}
className={cn(
"peer h-4 w-4 shrink-0 rounded-sm border border-primary ring-offset-background focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 disabled:cursor-not-allowed disabled:opacity-50 data-[state=checked]:bg-primary data-[state=checked]:text-primary-foreground",
className
)}
{...props}
>
<CheckboxPrimitive.Indicator
className={cn("flex items-center justify-center text-current")}
>
<Check className="h-4 w-4" />
</CheckboxPrimitive.Indicator>
</CheckboxPrimitive.Root>
));
Checkbox.displayName = CheckboxPrimitive.Root.displayName;

export { Checkbox };
119 changes: 119 additions & 0 deletions app/components/ui/select.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,119 @@
import * as SelectPrimitive from "@radix-ui/react-select";
import { Check, ChevronDown } from "lucide-react";
import * as React from "react";

import { cn } from "~/lib/utils";

const Select = SelectPrimitive.Root;

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-background 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 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",
position === "popper" &&
"data-[side=bottom]:translate-y-1 data-[side=left]:-translate-x-1 data-[side=right]:translate-x-1 data-[side=top]:-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(
"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 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">
<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,
};
24 changes: 24 additions & 0 deletions app/components/ui/textarea.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
import * as React from "react";

import { cn } from "~/lib/utils";

export interface TextareaProps
extends React.TextareaHTMLAttributes<HTMLTextAreaElement> {}

const Textarea = React.forwardRef<HTMLTextAreaElement, TextareaProps>(
({ className, ...props }, ref) => {
return (
<textarea
className={cn(
"flex min-h-[80px] w-full rounded-md border border-input bg-background px-3 py-2 text-sm ring-offset-background 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}
/>
);
}
);
Textarea.displayName = "Textarea";

export { Textarea };
43 changes: 43 additions & 0 deletions app/components/ui/toggle.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
import * as TogglePrimitive from "@radix-ui/react-toggle";
import { type VariantProps, cva } from "class-variance-authority";
import * as React from "react";

import { cn } from "~/lib/utils";

const toggleVariants = cva(
"inline-flex items-center justify-center rounded-md text-sm font-medium ring-offset-background transition-colors hover:bg-muted hover:text-muted-foreground focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 disabled:pointer-events-none disabled:opacity-50 data-[state=on]:bg-accent data-[state=on]:text-accent-foreground",
{
variants: {
variant: {
default: "bg-transparent",
outline:
"border border-input bg-transparent hover:bg-accent hover:text-accent-foreground",
},
size: {
default: "h-10 px-3",
sm: "h-9 px-2.5",
lg: "h-11 px-5",
},
},
defaultVariants: {
variant: "default",
size: "default",
},
}
);

const Toggle = React.forwardRef<
React.ElementRef<typeof TogglePrimitive.Root>,
React.ComponentPropsWithoutRef<typeof TogglePrimitive.Root> &
VariantProps<typeof toggleVariants>
>(({ className, variant, size, ...props }, ref) => (
<TogglePrimitive.Root
ref={ref}
className={cn(toggleVariants({ variant, size, className }))}
{...props}
/>
));

Toggle.displayName = TogglePrimitive.Root.displayName;

export { Toggle, toggleVariants };
5 changes: 5 additions & 0 deletions app/types/refs.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -23,3 +23,8 @@ export enum Currencies {
}

type Currency = keyof typeof Currencies;

type WithAction =
| { to: string; onClick?: never }
| { to?: never; onClick: () => void }
| { to?: never; onClick?: never };
3 changes: 3 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,10 @@
},
"dependencies": {
"@prisma/client": "^5.3.1",
"@radix-ui/react-checkbox": "^1.0.4",
"@radix-ui/react-select": "^1.2.2",
"@radix-ui/react-toast": "^1.1.4",
"@radix-ui/react-toggle": "^1.0.3",
"@remix-run/css-bundle": "*",
"@remix-run/node": "*",
"@remix-run/react": "*",
Expand Down

0 comments on commit 959ded2

Please sign in to comment.