You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Copy file name to clipboardExpand all lines: docs/STYLING.md
+47-9Lines changed: 47 additions & 9 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -82,7 +82,7 @@ These helpers are for component logic — see [Rendering](#4-rendering) for how
82
82
83
83
`defineProps` wires tokens to Puck editor fields (`src/lib/puck/define-props.ts`). It returns `{ fields, defaultProps }` to spread onto a `ComponentConfig`.
84
84
85
-
There are four field builders:
85
+
There are two builder namespaces:
86
86
87
87
```ts
88
88
const props =defineProps({
@@ -94,7 +94,16 @@ const props = defineProps({
94
94
layout: field.radio(layout, { label: "Layout" }),
95
95
96
96
// Responsive — per-breakpoint picker, also token-backed
The same token definition works for both static and responsive use — only the field builder differs.
129
+
The same token definition works for both static and responsive use. Numeric responsive fields do not need a token.
130
+
131
+
### Responsive field architecture
132
+
133
+
Responsive field descriptors are built on the server and rendered on the client, so the implementation is split intentionally:
134
+
135
+
- Shared kind definitions live in `src/components/puck/fields/responsive-kinds/*/shared.ts`.
136
+
- Client renderers live in `src/components/puck/fields/responsive-kinds/*/client.tsx`.
137
+
-`src/components/puck/fields/responsive-field.tsx` is the server-safe wrapper that turns a serializable descriptor into a Puck custom field.
138
+
-`src/components/puck/fields/responsive-field-client.tsx` is the client-only registry that maps `descriptor.kind` to the right renderer.
139
+
-`src/components/puck/fields/responsive-field-frame.tsx` owns the shared breakpoint UI; kind-specific controls only deal with their own value format.
140
+
141
+
This keeps the descriptor shape and the renderer associated by kind without pushing client code across the server boundary.
142
+
143
+
To add a new responsive field kind:
144
+
145
+
1. Add `shared.ts` and `client.tsx` under `src/components/puck/fields/responsive-kinds/<kind>/`.
146
+
2. Export the descriptor factory and type from `src/components/puck/fields/responsive-kinds/index.ts`.
147
+
3. Register the client component in `src/components/puck/fields/responsive-kinds/client-registry.tsx`.
148
+
4. Optionally add a convenience builder in `src/lib/puck/define-props.ts`.
119
149
120
150
### 4. Rendering
121
151
@@ -143,6 +173,8 @@ const classes = cn(
143
173
);
144
174
```
145
175
176
+
Responsive numeric props stay as data. Use `resolveAt(...)` or your own component logic when they need to influence layout or behavior; they do not go through `resolveResponsive(...)`.
177
+
146
178
## Tailwind source hints
147
179
148
180
Because `resolveResponsive` builds prefixed class names like `md:p-4` at runtime, Tailwind's scanner never sees them in source. Every responsive token needs a corresponding `@source inline(...)` directive in `src/app/styles.css`:
@@ -187,31 +219,37 @@ import { padding, bgColor, type Spacing, type Color } from "@/lib/puck/tokens";
Spread `props` onto the config and destructure in `render`. Use `resolveResponsive` for responsive props and direct `token.classes[value]` lookups for static ones:
238
+
Spread `props` onto the config and destructure in `render`. Use `resolveResponsive` for responsive token props, `resolveAt` or component logic for responsive numeric props, and direct `token.classes[value]` lookups for static ones:
0 commit comments