Deleted demo junk
This commit is contained in:
@@ -1,108 +0,0 @@
|
||||
import { useStore } from "@tanstack/react-form";
|
||||
|
||||
import { useFieldContext, useFormContext } from "../hooks/demo.form-context";
|
||||
|
||||
export function SubscribeButton({ label }: { label: string }) {
|
||||
const form = useFormContext();
|
||||
return (
|
||||
<form.Subscribe selector={(state) => state.isSubmitting}>
|
||||
{(isSubmitting) => (
|
||||
<button
|
||||
type="submit"
|
||||
disabled={isSubmitting}
|
||||
className="px-6 py-2 bg-indigo-600 text-white rounded-md hover:bg-indigo-700 focus:outline-none focus:ring-2 focus:ring-indigo-500 focus:ring-offset-2 transition-colors disabled:opacity-50"
|
||||
>
|
||||
{label}
|
||||
</button>
|
||||
)}
|
||||
</form.Subscribe>
|
||||
);
|
||||
}
|
||||
|
||||
function ErrorMessages({ errors }: { errors: Array<string | { message: string }> }) {
|
||||
return (
|
||||
<>
|
||||
{errors.map((error) => (
|
||||
<div key={typeof error === "string" ? error : error.message} className="text-red-500 mt-1 font-bold">
|
||||
{typeof error === "string" ? error : error.message}
|
||||
</div>
|
||||
))}
|
||||
</>
|
||||
);
|
||||
}
|
||||
|
||||
export function TextField({ label, placeholder }: { label: string; placeholder?: string }) {
|
||||
const field = useFieldContext<string>();
|
||||
const errors = useStore(field.store, (state) => state.meta.errors);
|
||||
|
||||
return (
|
||||
<div>
|
||||
<label htmlFor={label} className="block font-bold mb-1 text-xl">
|
||||
{label}
|
||||
<input
|
||||
value={field.state.value}
|
||||
placeholder={placeholder}
|
||||
onBlur={field.handleBlur}
|
||||
onChange={(e) => field.handleChange(e.target.value)}
|
||||
className="w-full px-4 py-2 rounded-md border border-gray-300 focus:outline-none focus:ring-2 focus:ring-indigo-500"
|
||||
/>
|
||||
</label>
|
||||
{field.state.meta.isTouched && <ErrorMessages errors={errors} />}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
export function TextArea({ label, rows = 3 }: { label: string; rows?: number }) {
|
||||
const field = useFieldContext<string>();
|
||||
const errors = useStore(field.store, (state) => state.meta.errors);
|
||||
|
||||
return (
|
||||
<div>
|
||||
<label htmlFor={label} className="block font-bold mb-1 text-xl">
|
||||
{label}
|
||||
<textarea
|
||||
value={field.state.value}
|
||||
onBlur={field.handleBlur}
|
||||
rows={rows}
|
||||
onChange={(e) => field.handleChange(e.target.value)}
|
||||
className="w-full px-4 py-2 rounded-md border border-gray-300 focus:outline-none focus:ring-2 focus:ring-indigo-500"
|
||||
/>
|
||||
</label>
|
||||
{field.state.meta.isTouched && <ErrorMessages errors={errors} />}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
export function Select({
|
||||
label,
|
||||
values,
|
||||
}: {
|
||||
label: string;
|
||||
values: Array<{ label: string; value: string }>;
|
||||
placeholder?: string;
|
||||
}) {
|
||||
const field = useFieldContext<string>();
|
||||
const errors = useStore(field.store, (state) => state.meta.errors);
|
||||
|
||||
return (
|
||||
<div>
|
||||
<label htmlFor={label} className="block font-bold mb-1 text-xl">
|
||||
{label}
|
||||
</label>
|
||||
<select
|
||||
name={field.name}
|
||||
value={field.state.value}
|
||||
onBlur={field.handleBlur}
|
||||
onChange={(e) => field.handleChange(e.target.value)}
|
||||
className="w-full px-4 py-2 rounded-md border border-gray-300 focus:outline-none focus:ring-2 focus:ring-indigo-500"
|
||||
>
|
||||
{values.map((value) => (
|
||||
<option key={value.value} value={value.value}>
|
||||
{value.label}
|
||||
</option>
|
||||
))}
|
||||
</select>
|
||||
{field.state.meta.isTouched && <ErrorMessages errors={errors} />}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
@@ -1,3 +0,0 @@
|
||||
import { createFormHookContexts } from "@tanstack/react-form";
|
||||
|
||||
export const { fieldContext, useFieldContext, formContext, useFormContext } = createFormHookContexts();
|
||||
@@ -1,17 +0,0 @@
|
||||
import { createFormHook } from "@tanstack/react-form";
|
||||
|
||||
import { Select, SubscribeButton, TextArea, TextField } from "../components/demo.FormComponents";
|
||||
import { fieldContext, formContext } from "./demo.form-context";
|
||||
|
||||
export const { useAppForm } = createFormHook({
|
||||
fieldComponents: {
|
||||
TextField,
|
||||
Select,
|
||||
TextArea,
|
||||
},
|
||||
formComponents: {
|
||||
SubscribeButton,
|
||||
},
|
||||
fieldContext,
|
||||
formContext,
|
||||
});
|
||||
@@ -10,72 +10,33 @@
|
||||
|
||||
import { Route as rootRouteImport } from './routes/__root'
|
||||
import { Route as IndexRouteImport } from './routes/index'
|
||||
import { Route as DemoTanstackQueryRouteImport } from './routes/demo.tanstack-query'
|
||||
import { Route as DemoFormSimpleRouteImport } from './routes/demo.form.simple'
|
||||
import { Route as DemoFormAddressRouteImport } from './routes/demo.form.address'
|
||||
|
||||
const IndexRoute = IndexRouteImport.update({
|
||||
id: '/',
|
||||
path: '/',
|
||||
getParentRoute: () => rootRouteImport,
|
||||
} as any)
|
||||
const DemoTanstackQueryRoute = DemoTanstackQueryRouteImport.update({
|
||||
id: '/demo/tanstack-query',
|
||||
path: '/demo/tanstack-query',
|
||||
getParentRoute: () => rootRouteImport,
|
||||
} as any)
|
||||
const DemoFormSimpleRoute = DemoFormSimpleRouteImport.update({
|
||||
id: '/demo/form/simple',
|
||||
path: '/demo/form/simple',
|
||||
getParentRoute: () => rootRouteImport,
|
||||
} as any)
|
||||
const DemoFormAddressRoute = DemoFormAddressRouteImport.update({
|
||||
id: '/demo/form/address',
|
||||
path: '/demo/form/address',
|
||||
getParentRoute: () => rootRouteImport,
|
||||
} as any)
|
||||
|
||||
export interface FileRoutesByFullPath {
|
||||
'/': typeof IndexRoute
|
||||
'/demo/tanstack-query': typeof DemoTanstackQueryRoute
|
||||
'/demo/form/address': typeof DemoFormAddressRoute
|
||||
'/demo/form/simple': typeof DemoFormSimpleRoute
|
||||
}
|
||||
export interface FileRoutesByTo {
|
||||
'/': typeof IndexRoute
|
||||
'/demo/tanstack-query': typeof DemoTanstackQueryRoute
|
||||
'/demo/form/address': typeof DemoFormAddressRoute
|
||||
'/demo/form/simple': typeof DemoFormSimpleRoute
|
||||
}
|
||||
export interface FileRoutesById {
|
||||
__root__: typeof rootRouteImport
|
||||
'/': typeof IndexRoute
|
||||
'/demo/tanstack-query': typeof DemoTanstackQueryRoute
|
||||
'/demo/form/address': typeof DemoFormAddressRoute
|
||||
'/demo/form/simple': typeof DemoFormSimpleRoute
|
||||
}
|
||||
export interface FileRouteTypes {
|
||||
fileRoutesByFullPath: FileRoutesByFullPath
|
||||
fullPaths:
|
||||
| '/'
|
||||
| '/demo/tanstack-query'
|
||||
| '/demo/form/address'
|
||||
| '/demo/form/simple'
|
||||
fullPaths: '/'
|
||||
fileRoutesByTo: FileRoutesByTo
|
||||
to: '/' | '/demo/tanstack-query' | '/demo/form/address' | '/demo/form/simple'
|
||||
id:
|
||||
| '__root__'
|
||||
| '/'
|
||||
| '/demo/tanstack-query'
|
||||
| '/demo/form/address'
|
||||
| '/demo/form/simple'
|
||||
to: '/'
|
||||
id: '__root__' | '/'
|
||||
fileRoutesById: FileRoutesById
|
||||
}
|
||||
export interface RootRouteChildren {
|
||||
IndexRoute: typeof IndexRoute
|
||||
DemoTanstackQueryRoute: typeof DemoTanstackQueryRoute
|
||||
DemoFormAddressRoute: typeof DemoFormAddressRoute
|
||||
DemoFormSimpleRoute: typeof DemoFormSimpleRoute
|
||||
}
|
||||
|
||||
declare module '@tanstack/react-router' {
|
||||
@@ -87,35 +48,11 @@ declare module '@tanstack/react-router' {
|
||||
preLoaderRoute: typeof IndexRouteImport
|
||||
parentRoute: typeof rootRouteImport
|
||||
}
|
||||
'/demo/tanstack-query': {
|
||||
id: '/demo/tanstack-query'
|
||||
path: '/demo/tanstack-query'
|
||||
fullPath: '/demo/tanstack-query'
|
||||
preLoaderRoute: typeof DemoTanstackQueryRouteImport
|
||||
parentRoute: typeof rootRouteImport
|
||||
}
|
||||
'/demo/form/simple': {
|
||||
id: '/demo/form/simple'
|
||||
path: '/demo/form/simple'
|
||||
fullPath: '/demo/form/simple'
|
||||
preLoaderRoute: typeof DemoFormSimpleRouteImport
|
||||
parentRoute: typeof rootRouteImport
|
||||
}
|
||||
'/demo/form/address': {
|
||||
id: '/demo/form/address'
|
||||
path: '/demo/form/address'
|
||||
fullPath: '/demo/form/address'
|
||||
preLoaderRoute: typeof DemoFormAddressRouteImport
|
||||
parentRoute: typeof rootRouteImport
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
const rootRouteChildren: RootRouteChildren = {
|
||||
IndexRoute: IndexRoute,
|
||||
DemoTanstackQueryRoute: DemoTanstackQueryRoute,
|
||||
DemoFormAddressRoute: DemoFormAddressRoute,
|
||||
DemoFormSimpleRoute: DemoFormSimpleRoute,
|
||||
}
|
||||
export const routeTree = rootRouteImport
|
||||
._addFileChildren(rootRouteChildren)
|
||||
|
||||
@@ -1,191 +0,0 @@
|
||||
import { createFileRoute } from "@tanstack/react-router";
|
||||
|
||||
import { useAppForm } from "../hooks/demo.form";
|
||||
|
||||
export const Route = createFileRoute("/demo/form/address")({
|
||||
component: AddressForm,
|
||||
});
|
||||
|
||||
function AddressForm() {
|
||||
const form = useAppForm({
|
||||
defaultValues: {
|
||||
fullName: "",
|
||||
email: "",
|
||||
address: {
|
||||
street: "",
|
||||
city: "",
|
||||
state: "",
|
||||
zipCode: "",
|
||||
country: "",
|
||||
},
|
||||
phone: "",
|
||||
},
|
||||
validators: {
|
||||
onBlur: ({ value }) => {
|
||||
const errors = {
|
||||
fields: {},
|
||||
} as {
|
||||
fields: Record<string, string>;
|
||||
};
|
||||
if (value.fullName.trim().length === 0) {
|
||||
errors.fields.fullName = "Full name is required";
|
||||
}
|
||||
return errors;
|
||||
},
|
||||
},
|
||||
onSubmit: ({ value }) => {
|
||||
console.log(value);
|
||||
// Show success message
|
||||
alert("Form submitted successfully!");
|
||||
},
|
||||
});
|
||||
|
||||
return (
|
||||
<div
|
||||
className="flex items-center justify-center min-h-screen bg-gradient-to-br from-purple-100 to-blue-100 p-4 text-white"
|
||||
style={{
|
||||
backgroundImage: "radial-gradient(50% 50% at 5% 40%, #f4a460 0%, #8b4513 70%, #1a0f0a 100%)",
|
||||
}}
|
||||
>
|
||||
<div className="w-full max-w-2xl p-8 rounded-xl backdrop-blur-md bg-black/50 shadow-xl border-8 border-black/10">
|
||||
<form
|
||||
onSubmit={(e) => {
|
||||
e.preventDefault();
|
||||
e.stopPropagation();
|
||||
form.handleSubmit();
|
||||
}}
|
||||
className="space-y-6"
|
||||
>
|
||||
<form.AppField name="fullName">{(field) => <field.TextField label="Full Name" />}</form.AppField>
|
||||
|
||||
<form.AppField
|
||||
name="email"
|
||||
validators={{
|
||||
onBlur: ({ value }) => {
|
||||
if (!value || value.trim().length === 0) {
|
||||
return "Email is required";
|
||||
}
|
||||
if (!/^[A-Z0-9._%+-]+@[A-Z0-9.-]+\.[A-Z]{2,}$/i.test(value)) {
|
||||
return "Invalid email address";
|
||||
}
|
||||
return undefined;
|
||||
},
|
||||
}}
|
||||
>
|
||||
{(field) => <field.TextField label="Email" />}
|
||||
</form.AppField>
|
||||
|
||||
<form.AppField
|
||||
name="address.street"
|
||||
validators={{
|
||||
onBlur: ({ value }) => {
|
||||
if (!value || value.trim().length === 0) {
|
||||
return "Street address is required";
|
||||
}
|
||||
return undefined;
|
||||
},
|
||||
}}
|
||||
>
|
||||
{(field) => <field.TextField label="Street Address" />}
|
||||
</form.AppField>
|
||||
|
||||
<div className="grid grid-cols-1 md:grid-cols-3 gap-4">
|
||||
<form.AppField
|
||||
name="address.city"
|
||||
validators={{
|
||||
onBlur: ({ value }) => {
|
||||
if (!value || value.trim().length === 0) {
|
||||
return "City is required";
|
||||
}
|
||||
return undefined;
|
||||
},
|
||||
}}
|
||||
>
|
||||
{(field) => <field.TextField label="City" />}
|
||||
</form.AppField>
|
||||
<form.AppField
|
||||
name="address.state"
|
||||
validators={{
|
||||
onBlur: ({ value }) => {
|
||||
if (!value || value.trim().length === 0) {
|
||||
return "State is required";
|
||||
}
|
||||
return undefined;
|
||||
},
|
||||
}}
|
||||
>
|
||||
{(field) => <field.TextField label="State" />}
|
||||
</form.AppField>
|
||||
<form.AppField
|
||||
name="address.zipCode"
|
||||
validators={{
|
||||
onBlur: ({ value }) => {
|
||||
if (!value || value.trim().length === 0) {
|
||||
return "Zip code is required";
|
||||
}
|
||||
if (!/^\d{5}(-\d{4})?$/.test(value)) {
|
||||
return "Invalid zip code format";
|
||||
}
|
||||
return undefined;
|
||||
},
|
||||
}}
|
||||
>
|
||||
{(field) => <field.TextField label="Zip Code" />}
|
||||
</form.AppField>
|
||||
</div>
|
||||
|
||||
<form.AppField
|
||||
name="address.country"
|
||||
validators={{
|
||||
onBlur: ({ value }) => {
|
||||
if (!value || value.trim().length === 0) {
|
||||
return "Country is required";
|
||||
}
|
||||
return undefined;
|
||||
},
|
||||
}}
|
||||
>
|
||||
{(field) => (
|
||||
<field.Select
|
||||
label="Country"
|
||||
values={[
|
||||
{ label: "United States", value: "US" },
|
||||
{ label: "Canada", value: "CA" },
|
||||
{ label: "United Kingdom", value: "UK" },
|
||||
{ label: "Australia", value: "AU" },
|
||||
{ label: "Germany", value: "DE" },
|
||||
{ label: "France", value: "FR" },
|
||||
{ label: "Japan", value: "JP" },
|
||||
]}
|
||||
placeholder="Select a country"
|
||||
/>
|
||||
)}
|
||||
</form.AppField>
|
||||
|
||||
<form.AppField
|
||||
name="phone"
|
||||
validators={{
|
||||
onBlur: ({ value }) => {
|
||||
if (!value || value.trim().length === 0) {
|
||||
return "Phone number is required";
|
||||
}
|
||||
if (!/^(\+\d{1,3})?\s?\(?\d{3}\)?[\s.-]?\d{3}[\s.-]?\d{4}$/.test(value)) {
|
||||
return "Invalid phone number format";
|
||||
}
|
||||
return undefined;
|
||||
},
|
||||
}}
|
||||
>
|
||||
{(field) => <field.TextField label="Phone" placeholder="123-456-7890" />}
|
||||
</form.AppField>
|
||||
|
||||
<div className="flex justify-end">
|
||||
<form.AppForm>
|
||||
<form.SubscribeButton label="Submit" />
|
||||
</form.AppForm>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
@@ -1,63 +0,0 @@
|
||||
import { createFileRoute } from "@tanstack/react-router";
|
||||
import { z } from "zod";
|
||||
|
||||
import { useAppForm } from "../hooks/demo.form";
|
||||
|
||||
// Routing
|
||||
export const Route = createFileRoute("/demo/form/simple")({
|
||||
component: SimpleForm,
|
||||
});
|
||||
|
||||
const schema = z.object({
|
||||
title: z.string().min(1, "Title is required"),
|
||||
description: z.string().min(1, "Description is required"),
|
||||
});
|
||||
|
||||
function SimpleForm() {
|
||||
const form = useAppForm({
|
||||
defaultValues: {
|
||||
title: "",
|
||||
description: "",
|
||||
},
|
||||
validators: {
|
||||
onBlur: schema,
|
||||
},
|
||||
onSubmit: ({ value }) => {
|
||||
console.log(value);
|
||||
// Show success message
|
||||
alert("Form submitted successfully!");
|
||||
},
|
||||
});
|
||||
|
||||
return (
|
||||
<div
|
||||
className="flex items-center justify-center min-h-screen bg-gradient-to-br from-purple-100 to-blue-100 p-4 text-white"
|
||||
style={{
|
||||
backgroundImage: "radial-gradient(50% 50% at 5% 40%, #add8e6 0%, #0000ff 70%, #00008b 100%)",
|
||||
}}
|
||||
>
|
||||
<div className="w-full max-w-2xl p-8 rounded-xl backdrop-blur-md bg-black/50 shadow-xl border-8 border-black/10">
|
||||
<form
|
||||
onSubmit={(e) => {
|
||||
e.preventDefault();
|
||||
e.stopPropagation();
|
||||
form.handleSubmit();
|
||||
}}
|
||||
className="space-y-6"
|
||||
>
|
||||
<form.AppField name="title">{(field) => <field.TextField label="Title" />}</form.AppField>
|
||||
|
||||
<form.AppField name="description">
|
||||
{(field) => <field.TextArea label="Description" />}
|
||||
</form.AppField>
|
||||
|
||||
<div className="flex justify-end">
|
||||
<form.AppForm>
|
||||
<form.SubscribeButton label="Submit" />
|
||||
</form.AppForm>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
@@ -1,25 +0,0 @@
|
||||
import { createFileRoute } from "@tanstack/react-router";
|
||||
import { useQuery } from "@tanstack/react-query";
|
||||
|
||||
export const Route = createFileRoute("/demo/tanstack-query")({
|
||||
component: TanStackQueryDemo,
|
||||
});
|
||||
|
||||
function TanStackQueryDemo() {
|
||||
const { data } = useQuery({
|
||||
queryKey: ["people"],
|
||||
queryFn: () => Promise.resolve([{ name: "John Doe" }, { name: "Jane Doe" }]),
|
||||
initialData: [],
|
||||
});
|
||||
|
||||
return (
|
||||
<div className="p-4">
|
||||
<h1 className="text-2xl mb-4">People list</h1>
|
||||
<ul>
|
||||
{data.map((person) => (
|
||||
<li key={person.name}>{person.name}</li>
|
||||
))}
|
||||
</ul>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
Reference in New Issue
Block a user