Membership ladder
Four named tiers each contain a movable benefit array. The schema requires the discount values to increase across the tier ladder.
Try the complete flow
Change the discount values to test cross-tier validation. Add and move benefits inside each tier. Connect the selected workspace, then add a pause window with an application-owned shortcut.
What this form demonstrates
- Four nested arrays under fixed object paths.
- Cross-tier schema validation.
- Query-provided workspace options through form context.
form.api.setValuefor connection state.form.api.getValuesandform.api.setValuefor pause shortcuts.- A live ladder preview through
useWatch.
Copy the source
"use client"
import {
,
,
,
,
} from "@tanstack/react-query"
import {
,
type ,
type ,
type ,
type ,
} from "form-please"
import { } from "form-please/default-slots"
import { } from "form-please/native-controls"
import { } from "react"
import { } from "zod"
const = .({
: .().(2, "Describe the benefit"),
: .().().(0),
})
const = .({
: .().(0).(80),
: .().(1, "Add at least one benefit"),
})
const =
.({
: .().(4, "Name the membership program"),
: .(["monthly", "quarterly", "annual"]),
: .().(1, "Choose a workspace"),
: .({
: .(),
: .(),
}),
: .({
: ,
: ,
: ,
: ,
}),
: .(
.({
: .().(1, "Choose a start date"),
: .().(1, "Choose an end date"),
: .().(3, "Explain the pause"),
}),
),
})
.((, ) => {
const = [
...,
...,
...,
...,
]
for (let = 1; < .; += 1) {
if (([] ?? 0) < ([ - 1] ?? 0)) {
.({
: "custom",
: ["tiers"],
: "Higher tiers cannot offer a smaller reduction",
})
break
}
}
for (const [, ] of ..()) {
if (. < .) {
.({
: "custom",
: ["pauseWindows", , "endsOn"],
: "The pause must end after it starts",
})
}
}
})
.(() => ({
...,
: .(.).(
(, ) => + ..,
0,
),
}))
type = <typeof >
type = <typeof >
type = {
readonly : readonly {
readonly : string
readonly : string
}[]
}
const = {
: "Common Ground Membership",
: "monthly",
: "commons-hub",
: { : false, : true },
: {
: {
: 0,
: [{ : "Monthly community digest", : 1 }],
},
: {
: 8,
: [{ : "Open desk sessions", : 2 }],
},
: {
: 15,
: [{ : "Project consultations", : 1 }],
},
: {
: 22,
: [{ : "Private program previews", : 4 }],
},
},
: [
{
: "2027-08-01",
: "2027-08-14",
: "Annual maintenance",
},
],
} satisfies
const = ({
: (),
: (),
})
const = .<>()
type = <typeof , >
function ({
,
,
}: {
readonly :
readonly : number
}) {
const = (: ["pauseWindows"][number]) => {
..(
"pauseWindows",
[.....("pauseWindows"), ],
{ : true },
)
}
return (
<
="form-please-complex__embedded"
="Pause calendar shortcuts"
>
<>Calendar shortcuts</>
< ="form-please-complex__choice-list">
<
={() =>
({
: "2027-12-24",
: "2027-12-31",
: "Winter closure",
})
}
="button"
>
Add winter closure
</>
<
={() =>
({
: "2028-04-10",
: "2028-04-12",
: "System migration",
})
}
="button"
>
Add migration window
</>
<>{} pause window(s) scheduled</>
</>
</>
)
}
function ({
,
,
,
}: {
readonly :
readonly : string
readonly : boolean
}) {
const = ({
: (: boolean) =>
({ , : }, 360),
})
let = "Workspace disconnected"
let = "Connect"
if () {
= "Workspace connected"
= "Disconnect"
}
if (.) = "Updating connection…"
return (
<
="form-please-complex__embedded"
="Workspace connection"
>
<>{}</>
<
={.}
={async () => {
const = await .(!)
..("connection.enabled", .)
}}
="button"
>
{}
</>
</>
)
}
const = .(, {
: [
{
: "section",
: "program",
: "Membership program",
: 2,
: [
{
: "field",
: "programName",
: "text",
: "Program name",
},
{
: "field",
: "billingCycle",
: "select",
: "Billing cycle",
: [
{ : "monthly", : "Monthly" },
{ : "quarterly", : "Quarterly" },
{ : "annual", : "Annual" },
],
},
{
: "field",
: "workspaceId",
: "select",
: "Member workspace",
: ({ }) => .,
},
{
: "field",
: "connection.syncExistingMembers",
: "checkbox",
: "Sync existing members",
},
],
},
...(),
{
: "array",
: "pauseWindows",
: "Pause windows",
:
"Dates can be entered directly or added from calendar shortcuts.",
: { : "", : "", : "" },
: [
{ : "field", : "startsOn", : "date", : "Starts" },
{ : "field", : "endsOn", : "date", : "Ends" },
{ : "field", : "reason", : "text", : "Reason" },
],
},
],
})
function () {
return [
{
: "section",
: "tier-seed",
: "Seed tier",
: [
{
: "field",
: "tiers.seed.discountPercent",
: "number",
: "Reduction percent",
: { : 0, : 80, : 1 },
},
{
: "array",
: "tiers.seed.benefits",
: "Benefits",
: { : "", : 0 },
: [
{
: "field",
: "label",
: "text",
: "Benefit",
},
{
: "field",
: "monthlyLimit",
: "number",
: "Monthly limit",
: { : 0, : 1 },
},
],
},
],
},
{
: "section",
: "tier-sprout",
: "Sprout tier",
: [
{
: "field",
: "tiers.sprout.discountPercent",
: "number",
: "Reduction percent",
: { : 0, : 80, : 1 },
},
{
: "array",
: "tiers.sprout.benefits",
: "Benefits",
: { : "", : 0 },
: [
{ : "field", : "label", : "text", : "Benefit" },
{
: "field",
: "monthlyLimit",
: "number",
: "Monthly limit",
: { : 0, : 1 },
},
],
},
],
},
{
: "section",
: "tier-canopy",
: "Canopy tier",
: [
{
: "field",
: "tiers.canopy.discountPercent",
: "number",
: "Reduction percent",
: { : 0, : 80, : 1 },
},
{
: "array",
: "tiers.canopy.benefits",
: "Benefits",
: { : "", : 0 },
: [
{ : "field", : "label", : "text", : "Benefit" },
{
: "field",
: "monthlyLimit",
: "number",
: "Monthly limit",
: { : 0, : 1 },
},
],
},
],
},
{
: "section",
: "tier-founder",
: "Founder tier",
: [
{
: "field",
: "tiers.founder.discountPercent",
: "number",
: "Reduction percent",
: { : 0, : 80, : 1 },
},
{
: "array",
: "tiers.founder.benefits",
: "Benefits",
: { : "", : 0 },
: [
{ : "field", : "label", : "text", : "Benefit" },
{
: "field",
: "monthlyLimit",
: "number",
: "Monthly limit",
: { : 0, : 1 },
},
],
},
],
},
] satisfies readonly <
,
typeof .,
>[]
}
export function () {
const [] = (
() => new ({ : { : { : false } } }),
)
return (
< ={}>
< />
</>
)
}
function () {
const = ({
: ["membership-draft"],
: () => (, 380),
})
const = ({
: ["member-workspaces"],
: () =>
(
[
{ : "commons-hub", : "Commons Hub" },
{ : "field-notes", : "Field Notes Circle" },
{ : "makers-union", : "Makers Union" },
],
460,
),
})
const = ({
: (: ) =>
({ : . + 500 }, 440),
})
const [, ] = ("Membership draft loaded.")
const = .(, {
: ,
: { : . ?? [] },
async ({ }) {
try {
const = await .()
(`Membership revision ${.} saved.`)
} catch {
(
"The membership service did not respond. Your edits remain local.",
)
}
},
})
if (. || .)
return (
< ="form-please-complex">
Loading membership ladder…
</>
)
if (. || .)
return (
< ="form-please-complex">
Could not load the membership editor.
</>
)
let =
if (.) = "Saving ladder…"
const = ..()
return (
<
="Membership ladder example"
="form-please-complex"
>
< ="form-please-complex__kicker">Cascading four-tier editor</>
< ="form-please-complex__summary">
Four nested benefit arrays, monotonic reductions, a remote workspace
connection, and calendar-assisted pause windows stay synchronized.
</>
<. ="form-please-complex__form" ={}>
<
={..}
={}
={.}
/>
<
="Membership ladder preview"
="form-please-complex__preview"
>
<>Reduction ladder</>
<>
Seed {...}% → Sprout{" "}
{...}% → Canopy{" "}
{...}% → Founder{" "}
{...}%
</>
</>
< ={..} ={} />
< ="form-please-complex__actions">
<. ="form-please-complex__primary">
Save membership ladder
</.>
< ="polite">{}</>
</>
</.>
</>
)
}
function <>(: , : number): <> {
return new (() =>
.(() => (), ),
)
}Compare the other workflows in Examples.