Module Fields — Proposal
Status: PROPOSAL (hand-written, for review). Once approved, these bake into the field
registry (studio/lib/fields.ts) that drives the Fields editor in Module Preview and the
Builder, and MODULES.md (generated) gains a Fields column. Until then this doc is the spec.
Already implemented today (minimal set): module title, Show header, and a few text fields
per module (Product name/price/CTA, Ticketing event meta, Event Reminder meta + status select,
Profile name/handle/meta, Text heading/signature). Everything else below is proposed.
Field type vocabulary
| Type |
Editor control |
Notes |
text |
Single-line input |
|
textarea |
Multi-line input |
Paragraph copy |
number |
Stepper/input |
Min/max where noted |
select |
Dropdown |
Closed set of options |
toggle |
Switch |
Behaviour/visibility options |
image |
Upload / URL |
Asset pipeline lands in Phase 7; URL until then |
media |
Upload / URL |
Video or audio source |
color |
Swatch picker |
Hex |
url |
URL input |
Validated |
date / time |
Picker |
Stored as display label until backend |
list<…> |
Repeatable rows (add/remove/reorder) |
Item sub-fields listed per module |
Common to every module (via ModuleShell):
| Field |
Key |
Type |
Notes |
| Module title |
title |
text |
Top-left header label |
| Show header |
header |
toggle |
Hides the title/CTA row entirely |
| Header CTA label |
ctaLabel |
text |
Optional pill top-right (proposed — currently a JSX slot) |
Standard modules
Text (text)
| Field |
Key |
Type |
Notes |
| Heading |
title |
text |
✅ exists |
| Paragraphs |
paragraphs |
list<textarea> |
Currently fixed sample copy |
| Signature |
signature |
text |
✅ exists |
Social (social)
| Field |
Key |
Type |
Notes |
| Links |
links |
list |
Item: platform (select: instagram / x / tiktok / spotify / youtube / website) · label (text) · url (url) |
Options: icon-only mode (toggle) for a compact row of icons.
Image Carousel (image-carousel)
| Field |
Key |
Type |
Notes |
| Images |
images |
list |
Item: image · alt (text) · caption (text) |
| Aspect ratio |
ratio |
select |
4:5 (default) / 1:1 / 16:9 |
| Show captions |
showCaptions |
toggle |
|
Profile (profile)
Mostly data-bound (renders the signed-in portal user, not editor content). Editor fields:
| Field |
Key |
Type |
Notes |
| Show handle |
showHandle |
toggle |
|
| Show meta line |
showMeta |
toggle |
e.g. "Member since…" |
Note: name/handle/avatar come from the user record at runtime; the current text fields are
preview-only stand-ins.
Notifications (notifications)
Data-bound (system notifications). Editor fields:
| Field |
Key |
Type |
Notes |
| Max items |
maxItems |
number |
Default 3 |
| Empty-state copy |
emptyText |
text |
Shown when there are none |
Collection (collection)
| Field |
Key |
Type |
Notes |
| Source |
source |
select |
Owned items (data-bound, default) / Manual list |
| Manual items |
items |
list |
Item: title · subtitle · image · link (url). Only when Source = Manual |
Advanced modules
Product (product)
| Field |
Key |
Type |
Notes |
| Product name |
name |
text |
✅ exists |
| Media |
media |
list<image> |
Gallery behind the pagination dots |
| Meta blocks |
meta |
list |
Item: label (text) · sub (text) — e.g. drop info, fabric |
| Colour options |
colorOptions |
list |
Item: name (text) · swatch (color) |
| Size options |
sizeOptions |
list<text> |
Populates the Size select |
| Size guide |
sizeGuideLabel + sizeGuideUrl |
text + url |
Badge next to the Size select |
| Max quantity |
maxQuantity |
number |
Stepper cap |
| Total price |
price |
text |
✅ exists · later: number + currency, derived per variant |
| CTA label |
actionLabel |
text |
✅ exists |
| Sold out |
soldOut |
toggle |
Mutes options, disables CTA |
Options: show pagination dots (toggle) · show size guide (toggle).
Ticketing (ticketing)
| Field |
Key |
Type |
Notes |
| Event title |
eventTitle |
text |
✅ exists |
| Date |
dateLabel |
date |
✅ exists (as text) |
| Times |
timeLabel |
time range |
✅ exists (as text) |
| Venue / Location |
venue / location |
text |
✅ exist |
| Media |
media |
list<image> |
Flyer gallery + pagination dots |
| Ticket tiers |
tiers |
list |
Item: name (text) · price (text) · capacity (number, optional) · sold out (toggle) |
| CTA label |
actionLabel |
text |
✅ exists |
Options: sold-out tier behaviour (select: show muted / hide) · show times (toggle).
Linked: placing this module auto-adds Event Reminder to the Hub (existing rule).
Event Reminder (ticket)
| Field |
Key |
Type |
Notes |
| Event title / Date / Venue / Seat |
eventTitle dateLabel venue seat |
text |
✅ exist |
| Status |
status |
select |
valid / used / transferred — ✅ exists |
| Details |
details |
list |
Item: label · value (order no., entry door, holder) |
| CTA label |
actionLabel |
text |
"View Tickets" |
Options: show details expander (toggle).
Note: in production this is data-bound to the user's actual ticket; editor fields are the template.
Music Player (music-player)
| Field |
Key |
Type |
Notes |
| Tracks |
tracks |
list |
Item: title (text) · artist (text) · audio (media) · cover (image) · duration (auto from file) |
Options: auto-advance to next track (toggle, default on) · show tracklist (toggle) ·
tracklist starts collapsed (toggle).
Video (video)
| Field |
Key |
Type |
Notes |
| Video |
src |
media |
|
| Poster |
poster |
image |
Frame shown before play |
Options: loop (toggle) · start muted (toggle) · show fullscreen CTA (toggle, default on).
Notes for implementation (later, not now)
list and image/media are new field types — the FieldsEditor needs repeatable rows and an
asset input (URL until the Phase 7 asset pipeline).
- Data-bound fields (Profile, Notifications, Collection-owned, Event Reminder) render sample data
in Studio and real data in production — the schema should mark them
bound: true so the
Builder labels them accordingly instead of offering content inputs.
- When approved,
build-modules-doc.ts should render each module's fields into MODULES.md from
the registry — keeping the generated doc the single mirror (this file then retires or becomes
the changelog of field decisions).