Skip to content

Instantly share code, notes, and snippets.

@sgrove
Created October 21, 2023 16:39
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save sgrove/94370dcbc7fe99a05b35924e1e6221fb to your computer and use it in GitHub Desktop.
Save sgrove/94370dcbc7fe99a05b35924e1e6221fb to your computer and use it in GitHub Desktop.
I would like you to translate TypeScript react components to Rescript react components, using some examples I will provide as a guide. Any time you are unsure as to the equivalency between a TypeScript construct and its Rescript counterpart, add it to a "Future examples to provide" list you output at the end after the code.
Let's begin!
Heres PromptEditor.tsx:
```
import React, { useState } from "react";
import { Button } from "@/components/ui/button";
import { Input } from "@/components/ui/input";
import { Textarea } from "@/components/ui/textarea";
import { Tabs, TabsContent, TabsList, TabsTrigger } from "@/components/ui/tabs";
import { ClipboardEdit, TestTube2, Redo2 } from "lucide-react";
console.log("Hello console!")
console.log("Hello console with", "three", "arguments!");
export const PromptEditor: React.FC = () => {
const [code, setCode] = useState('');
const [inputSchema, setInputSchema] = useState('');
const [outputSchema, setOutputSchema] = useState('');
const [tab, setTab] = useState('edit');
const [list, setList] = useState<string[]>([]);
const [users, setUsers] = useState([{
id: 1,
name: "John Doe",
email: "temp@gmail.com"
}]);
const resetSchemas = () => {
setInputSchema('');
setOutputSchema('');
}
const messageName = "World"
return (
<div className="dark:bg-gray-800 dark:text-gray-200 p-6">
<h2 className="text-xl mb-5"> LMP Prompt with schema editor {"Hello, " + messageName + "!"} </h2>
<h2 className="text-xl mb-5"> {`We're so happy to have you, ${messageName}`} </h2>
<ol>
{users.map((user, index) => {
return <li key={user.id}> {`${index}. ` + user.name} </li>
})
}
</ol>
<h2 className="text-xl mb-5">GraphQL SDL Schema With Code Editor</h2>
<Tabs defaultValue="edit" onChange={(newTab) => setTab(newTab)} className="w-full" asChild>
<TabsList className="grid w-full grid-cols-2">
<TabsTrigger value="edit">Edit</TabsTrigger>
<TabsTrigger value="try">Try</TabsTrigger>
</TabsList>
<TabsContent value="edit">
<div className="flex space-x-4">
<Textarea
value={code}
onChange={(e) => setCode(e.target.value)}
year="text"
placeholder="Enter handlebars-like code"
className="w-1/2 h-60 dark:bg-gray-700 resize-none"
/>
<div className="w-1/2 space-y-2">
<Input
value={inputSchema}
onChange={(e) => setInputSchema(e.target.value)}
type="text"
placeholder="Enter input SDL schema"
className="dark:bg-gray-700"
/>
<Input
value={outputSchema}
onChange={(e) => setOutputSchema(e.target.value)}
type="text"
placeholder="Enter output SDL schema"
className="dark:bg-gray-700"
/>
<div className="flex space-x-4 mt-1">
<Button onClick={resetSchemas} variant="outline">
<Redo2 className="h-4 w-4" /> Reset Schema
</Button>
<Button variant="outline">
<ClipboardEdit className="h-4 w-4" /> Copy Schema
</Button>
<Button onClick={(event) => {
console.log("Button clicked:", event.target.value)
}} variant="outline">
<TestTube2 className="h-4 w-4" /> Test Schema
</Button>
</div>
</div>
</div>
</TabsContent>
<TabsContent value="try">
<div>
{/* Generate form here based on input SDL schema */}
<div className="mb-4">
{/* Show output here */}
</div>
</div>
</TabsContent>
</Tabs>
</div>
)
}
export default PromptEditor;
```
Here's PromptEditor.res:
```
module Redo2 = {
@module("lucide-react") @react.component
external make: (~className: string=?) => React.element = "Redo2"
}
module ClipboardEdit = {
@module("lucide-react") @react.component
external make: (~className: string=?) => React.element = "ClipboardEdit"
}
module TestTube2 = {
@module("lucide-react") @react.component
external make: (~className: string=?) => React.element = "TestTube2"
}
module Button = {
@module("@/components/ui/button") @react.component
external make: (
~variant: string=?,
~onClick: ReactEvent.Mouse.t => unit=?,
~children: React.element,
~className: string=?,
) => React.element = "Button"
}
module Input = {
@module("@/components/ui/input") @react.component
external make: (
~type_: string,
~value: string=?,
~onChange: ReactEvent.Form.t => unit,
~placeholder: string,
~className: string=?,
~punningExample: string=?,
) => React.element = "Input"
}
module Textarea = {
@module("@/components/ui/textarea") @react.component
external make: (
~year: string,
~value: string=?,
~onChange: ReactEvent.Form.t => unit,
~placeholder: string,
~className: string=?,
) => React.element = "Textarea"
}
module Tabs = {
@module("@/components/ui/tabs") @react.component
external make: (
~defaultValue: string,
~onChange: string => unit,
~className: string=?,
~children: React.element,
~asChild: bool,
) => React.element = "Tabs"
}
module TabsContent = {
@module("@/components/ui/tabs") @react.component
external make: (~value: string, ~className: string=?, ~children: React.element) => React.element =
"TabsContent"
}
module TabsList = {
@module("@/components/ui/tabs") @react.component
external make: (~className: string=?, ~children: React.element) => React.element = "TabsList"
}
module TabsTrigger = {
@module("@/components/ui/tabs") @react.component
external make: (~value: string, ~children: React.element) => React.element = "TabsTrigger"
}
type user = {
id: int,
name: string,
email: string,
}
Console.log("Hello console!")
Console.log3("Hello console with", "three", "arguments!")
// Note: Array syntax in rescript is the same as in JS, e.g. [1, 2, 3]
// NEVER use [||] in rescript, it's a different thing
@react.component
let make = () => {
let (code, setCode) = React.useState(() => "")
let (inputSchema, setInputSchema) = React.useState(() => "")
let (outputSchema, setOutputSchema) = React.useState(() => "")
let (tab, setTab) = React.useState(() => "edit")
let (list, setList) = React.useState(() => [])
let (users, setUsers) = React.useState(() => [
{
id: 1,
name: "John Doe",
email: "temp@gmail.com",
},
])
let resetSchemas = () => {
setInputSchema(_ => "")
setOutputSchema(_ => "")
}
let punningExample = "this-is-how-punning-works-in-rescript"
let messageName = "World"
<div className="dark:bg-gray-800 dark:text-gray-200 p-6">
<h2 className="text-xl mb-5">
{"LMP Prompt with schema editor"->React.string}
{("Hello, " ++ messageName ++ "!")->React.string}
</h2>
<h2 className="text-xl mb-5"> {`We're so happy to have you, ${messageName}`->React.string} </h2>
<ol>
{users
->Array.mapWithIndex((user, index) => {
<li key={user.id->Int.toString}>
{`${index->Int.toString}. `->React.string}
{user.name->React.string}
</li>
})
->React.array}
</ol>
<Tabs
defaultValue="edit"
onChange={newTab => setTab(_ => newTab)}
className="w-full"
// In React a prop passed by itself, e.g. `asChild`, is the same as `asChild={true}`
// In rescript, it's "punned", so it's equivalent to `asChild={asChild}`
asChild={true}>
<TabsList className="grid w-full grid-cols-2">
<TabsTrigger value="edit"> {"Edit"->React.string} </TabsTrigger>
<TabsTrigger value="try"> {"Try"->React.string} </TabsTrigger>
</TabsList>
<TabsContent value="edit">
<div className="flex space-x-4">
<Textarea
value={code}
onChange={e => setCode(Obj.magic(e->ReactEvent.Form.target)["value"])}
year="text"
placeholder="Enter handlebars-like code"
className="w-1/2 h-60 dark:bg-gray-700 resize-none"
/>
<div className="w-1/2 space-y-2">
<Input
value={inputSchema}
onChange={e => setCode(Obj.magic(e->ReactEvent.Form.target)["value"])}
type_="text"
placeholder="Enter input SDL schema"
className="dark:bg-gray-700"
punningExample
/>
<Input
value={outputSchema}
onChange={e => setCode(Obj.magic(e->ReactEvent.Form.target)["value"])}
type_="text"
placeholder="Enter output SDL schema"
className="dark:bg-gray-700"
/>
<div className="flex space-x-4 mt-1">
<Button onClick={_ => resetSchemas()} variant="outline">
<Redo2 className="h-4 w-4" />
{"Reset Schema"->React.string}
</Button>
<Button variant="outline">
<ClipboardEdit className="h-4 w-4" />
{"Copy Schema"->React.string}
</Button>
<Button
variant="outline"
onClick={event => {
Console.log2(
"Button clicked:",
Obj.magic(event->ReactEvent.Mouse.target)["value"],
)
}}>
<TestTube2 className="h-4 w-4" />
{"Test Schema"->React.string}
</Button>
</div>
</div>
</div>
</TabsContent>
<TabsContent value="try">
<div>
// Generate form here based on input SDL schema
<div className="mb-4">
//Show output here
</div>
</div>
</TabsContent>
</Tabs>
</div>
}
```
Now please do the equivalent for the following TypeScript file:
```
import React from "react";
import { Button } from "@/components/ui/button";
import {
Card,
CardContent,
CardDescription,
CardFooter,
CardHeader,
CardTitle,
} from "@/components/ui/card";
import { Vegan, Apple, Banana } from "lucide-react";
import {
Tooltip,
TooltipContent,
TooltipProvider,
TooltipTrigger,
} from "@/components/ui/tooltip";
export const FitnessCoachingPricingComponent = () => {
const plans = [
{
name: "Green Fit",
icon: <Vegan className="h-6 w-6" />,
features: ["5 Veggie Meals", "Fitness Trainer Access", "24/7 Health Support", "Daily Nutrition Counseling"],
price: "$49",
},
{
name: "Apple Active",
icon: <Apple className="h-6 w-6" />,
features: ["7 Balanced Meals", "Fitness Trainer Access", "24/7 Health Support", "Weekly Health Checkups", "Personal Nutritionist Calls"],
price: "$69",
},
{
name: "Vegan Vitality",
icon: <Banana className="h-6 w-6" />,
features: ["Unlimited Vegan Meals", "Fitness Trainer Access", "24/7 Health Support", "Weekly Health Checkups",
"Personal Nutritionist Calls", "Priority Food Delivery"],
price: "$99",
},
];
return (
<div className="flex flex-col md:flex-row justify-around items-center px-4 py-8 bg-gradient-to-r from-green-400 via-blue-500 to-purple-600 rounded-md shadow-lg">
{plans.map((plan) => (
<Card key={plan.name} className="m-4 md:m-0 p-6 bg-white rounded-lg shadow-md">
<CardHeader className="flex flex-col items-center space-y-2">
{plan.icon}
<CardTitle className="text-2xl font-bold text-gray-800">{plan.name}</CardTitle>
<CardDescription className="text-xl text-gray-600">{plan.price}/mo</CardDescription>
</CardHeader>
<CardContent className="space-y-2 py-6">
{plan.features.map((feature) => (
<TooltipProvider key={feature}>
<Tooltip>
<TooltipTrigger asChild>
<p className="flex items-center space-x-1 cursor-pointer text-gray-500">
<span className="w-4 h-4 bg-green-500 rounded-full inline-block"></span>
<CardDescription>{feature}</CardDescription>
</p>
</TooltipTrigger>
<TooltipContent className="bg-white text-black dark:bg-gray-700 dark:text-white">
<p>{feature}</p>
</TooltipContent>
</Tooltip>
</TooltipProvider>
))}
</CardContent>
<CardFooter className="pt-8">
<Button variant="outline" className="text-white bg-blue-500 hover:bg-blue-400 dark:bg-yellow-500 dark:hover:bg-yellow-400 transition-colors w-full py-2 rounded-lg" onClick={(event) => {
console.log("Button alt clicked?", event.altKey)
}}>Get {plan.name}</Button>
</CardFooter>
</Card>
))}
</div>
);
};
export default FitnessCoachingPricingComponent;
```
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment