Skip to content

Commit 42e915e

Browse files
odenirdevclaude
andcommitted
docs: align README + doc-comments to Atomic Design scheme
The runtime already migrated to the `{owner}-{layer}.{name}` palette (preset-*/custom-*), but the README still documented the retired press.*/section.*/chrome.* scheme and three doc-comments cited old uids — making the "names centralized" contract false in the docs a new adopter reads first. - README: rewrite the custom-blocks / override / reuse sections to preset-*/custom-*; document universal custom placement (all engine DZs, editor decides) vs. curated preset placement; fix type names (PressButton -> PresetAtomButton), registries (referenceBlocks -> atomBlocks + organismBlocks), uids and folder paths. - shared/src/index.ts, plugins/cookie-consent/types.ts: fix stale uid examples in doc-comments (press.nav-item -> preset-molecule.nav-item; press.cookie-* -> preset-config.cookie-*). - playground seed: add a demo navbar with two url-based nav-items so the preset-molecule.nav-item molecule renders live (engine seed stays empty by convention). Docs-only + playground seed; no API/behavior change, no new changeset (the atomic-design-components major already covers the rename). Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
1 parent 936ece7 commit 42e915e

4 files changed

Lines changed: 59 additions & 38 deletions

File tree

‎README.md‎

Lines changed: 41 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -102,35 +102,41 @@ fetches them at **runtime** (ISR ~60s), so changes appear **without a redeploy**
102102
CMS is unreachable the site renders unbranded/default-themed rather than crashing — there
103103
is no `press.config` fallback for identity by design.
104104

105-
**Custom blocks** — the engine ships a `press.*` core palette (paragraph, heading, list,
106-
quote, image, button, separator, spacer). To add your own, drop a Strapi component under
107-
`packages/cms/src/components/custom/`, a matching React component under
105+
**Custom blocks** — the engine ships a `preset-*` Atomic Design palette: atoms
106+
(`preset-atom.paragraph`, `heading`, `list`, `quote`, `image`, `button`, `separator`,
107+
`spacer`) and organisms (`preset-organism.hero`, `cta`, `navbar`, `footer`). To add your
108+
own, drop a Strapi component under `packages/cms/src/components/custom-<layer>/` (the
109+
folder names the atomic layer, e.g. `custom-organism/`), a matching React component under
108110
`packages/web/blocks/custom/`, and wire it in `packages/web/blocks/custom/index.ts`:
109111

110112
```ts
111113
export const customBlocks: Record<string, ComponentType<any>> = {
112-
'custom.callout': Callout,
114+
'custom-organism.callout': Callout,
113115
};
114116
```
115117

116-
Any `custom.*` component is auto-admitted into the page's Dynamic Zone, and the
117-
materialized host passes this map to its block renderer — so your blocks render
118-
server-side alongside the engine's built-in blocks.
118+
Every `custom-*` component is auto-admitted into **all** engine Dynamic Zones — the page
119+
`body` and the site-setting `header`/`footer` — so the editor decides placement in the
120+
picker (unlike the engine's own `preset-*` blocks, whose placement is curated per
121+
content-type). The materialized host passes this map to its block renderer, so your blocks
122+
render server-side alongside the engine's built-in blocks.
119123

120-
**Overriding a reference block** — the `press.*` palette ships as defaults, not a
124+
**Overriding a reference block** — the `preset-*` palette ships as defaults, not a
121125
sealed set. The block renderer merges your map *over* the engine's
122-
(`{ ...referenceBlocks, ...customBlocks }`), so mapping the **same key** shadows a
123-
built-in with your own React component — markup and behavior become yours. This is
124-
**web-only**: the CMS still serves `press.button` and the editing experience is
125-
unchanged, so existing content keeps rendering.
126+
(`{ ...atomBlocks, ...organismBlocks, ...customBlocks }`), so mapping the **same key**
127+
shadows a built-in with your own React component — markup and behavior become yours. Any
128+
`preset-atom.*` or `preset-organism.*` key is overridable this way (e.g.
129+
`'preset-organism.hero': MyHero`). This is **web-only**: the CMS still serves
130+
`preset-atom.button` and the editing experience is unchanged, so existing content keeps
131+
rendering.
126132

127133
```tsx
128134
// packages/web/blocks/custom/Button.tsx — take the same props the engine block gets.
129-
import type { PressButton } from '@ogs-tech/press-web';
135+
import type { PresetAtomButton } from '@ogs-tech/press-web';
130136

131-
export function Button({ label, href, variant }: PressButton) {
137+
export function Button({ label, href, variant }: PresetAtomButton) {
132138
// Keep `data-block` to inherit the default theme.css styling and only tweak markup;
133-
// drop it to fully own the look (the engine's `[data-block="press.button"]` rule
139+
// drop it to fully own the look (the engine's `[data-block="preset-atom.button"]` rule
134140
// then matches nothing and goes inert).
135141
return <a className="cta" href={href} data-variant={variant ?? 'primary'}>{label}</a>;
136142
}
@@ -139,19 +145,19 @@ export function Button({ label, href, variant }: PressButton) {
139145
```ts
140146
// packages/web/blocks/custom/index.ts — map the SAME key to shadow the default.
141147
export const customBlocks: Record<string, ComponentType<any>> = {
142-
'custom.callout': Callout,
143-
'press.button': Button, // overrides the engine's press.button
148+
'custom-organism.callout': Callout,
149+
'preset-atom.button': Button, // overrides the engine's preset-atom.button
144150
};
145151
```
146152

147153
Your override is yours to maintain: `press upgrade` keeps updating the engine's
148154
*default* (which your map overrides) but never touches your component. If a future
149-
engine version changes a block's prop **shape**, the generated `Press*` type changes
155+
engine version changes a block's prop **shape**, the generated `Preset*` type changes
150156
and `tsc` flags your override at its call site — so drift fails loud rather than
151157
silently rendering wrong.
152158

153159
**Reusing a reference block inside a custom block** — the inverse of overriding: instead
154-
of *replacing* a `press.*` block you *embed* one. Each reference block is exported
160+
of *replacing* a `preset-*` block you *embed* one. Each reference block is exported
155161
individually from `@ogs-tech/press-web` (`Heading`, `Paragraph`, `List`, `Quote`,
156162
`Image`, `Button`, `Separator`, `Spacer`), so a custom block can reuse the engine's
157163
server-rendered, theme-aware markup instead of reimplementing it. You feed each one from
@@ -160,27 +166,27 @@ your **own** schema fields — the presentation is reused, the data stays yours.
160166
```tsx
161167
// packages/web/blocks/custom/Callout.tsx
162168
import { Heading, Paragraph, Button } from '@ogs-tech/press-web';
163-
import type { CustomCallout } from '<name>-shared/types';
169+
import type { CustomOrganismCallout } from '<name>-shared/types';
164170

165-
export function Callout({ title, body, ctaLabel, ctaHref }: CustomCallout) {
171+
export function Callout({ title, body, ctaLabel, ctaHref }: CustomOrganismCallout) {
166172
return (
167-
<aside data-block="custom.callout">
168-
<Heading text={title} level="3" /> {/* press.heading → { text, level } */}
169-
<Paragraph content={body} /> {/* press.paragraph → { content } */}
173+
<aside data-block="custom-organism.callout">
174+
<Heading text={title} level="3" /> {/* preset-atom.heading → { text, level } */}
175+
<Paragraph content={body} /> {/* preset-atom.paragraph → { content } */}
170176
<Button label={ctaLabel} href={ctaHref} variant="primary" />
171177
</aside>
172178
);
173179
}
174180
```
175181

176-
The one gotcha is **prop shape** — the generated `Press*` types are the source of truth.
182+
The one gotcha is **prop shape** — the generated `Preset*` types are the source of truth.
177183
`Heading` wants `{ text, level }` and `Button` wants `{ label, href, variant }` (plain
178184
scalars), but `Paragraph`/`List`/`Quote` want `{ content }` — a Strapi **blocks** value,
179185
*not* a string. So to feed a `Paragraph`, the custom block's own schema needs a `blocks`
180186
attribute:
181187

182188
```jsonc
183-
// packages/cms/src/components/custom/callout.json
189+
// packages/cms/src/components/custom-organism/callout.json
184190
"attributes": {
185191
"title": { "type": "string", "required": true },
186192
"body": { "type": "blocks" }, // ← feeds <Paragraph content={body} />
@@ -189,12 +195,12 @@ attribute:
189195
}
190196
```
191197

192-
The embedded child carries its own `data-block` (e.g. `press.heading`), so it inherits
193-
the default theme.css styling for free; the wrapper's `data-block="custom.callout"` is
194-
your block's own hook. Reuse is **web-only and decided by you** — the editor fills your
195-
custom block's flat fields, not a nested press block; you choose the layout. (Letting the
196-
*editor* compose `press.*` blocks inside a custom component is a different, schema-level
197-
feature and not currently supported.)
198+
The embedded child carries its own `data-block` (e.g. `preset-atom.heading`), so it
199+
inherits the default theme.css styling for free; the wrapper's
200+
`data-block="custom-organism.callout"` is your block's own hook. Reuse is **web-only and
201+
decided by you** — the editor fills your custom block's flat fields, not a nested preset
202+
block; you choose the layout. (Letting the *editor* compose `preset-*` blocks inside a
203+
custom component is a different, schema-level feature and not currently supported.)
198204

199205
## Updating the engine
200206

@@ -221,8 +227,9 @@ code.
221227

222228
- `packages/cli` — `@ogs-tech/create-press`: the run-once scaffolder invoked via `pnpm create @ogs-tech/press`; not added as a project dependency.
223229
- `packages/cms` — the **engine** Strapi plugin (`@ogs-tech/press-cms`): ships the
224-
`page` + `site-setting` content-types, injects the `press.*` reference palette into
225-
the page Dynamic Zone, and serves the type-sync contract at `/api/press/schema`.
230+
`page` + `site-setting` content-types, injects the `preset-*` Atomic Design palette
231+
(atoms/molecules/organisms/config) into the engine Dynamic Zones, and serves the
232+
type-sync contract at `/api/press/schema`.
226233
- `packages/web` — the **engine** web layer (`@ogs-tech/press-web`): the Next host
227234
template, block renderer, config helpers, and CMS→types sync.
228235
- `packages/shared` — `@ogs-tech/press-shared`: framework-agnostic contract types

‎apps/playground/packages/cms/scripts/seed.mjs‎

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
// cms/scripts/seed.mjs — One-shot sample content for the cms host. Boots it
22
// programmatically (CMS server must be STOPPED), fills the Site Settings single
3-
// type (identity/SEO + theme), uploads a few tiny PNGs, and creates a PUBLISHED
3+
// type (identity/SEO + theme + a demo navbar), uploads a few tiny PNGs, and creates a PUBLISHED
44
// 'home' page that showcases the Atomic Design core palette (heading, paragraph,
55
// list, quote, separator, image, button, spacer) plus the adopter's custom-organism.callout,
66
// so the first `press dev` renders a branded, themed site.
@@ -53,6 +53,20 @@ const SITE_SETTINGS = {
5353
border: 'rgba(20,32,54,0.12)',
5454
},
5555
themeRadius: { xs: '6px', sm: '10px', md: '14px', lg: '20px' },
56+
// Demo chrome: a navbar carrying two url-based preset-molecule.nav-item molecules, so a
57+
// molecule renders live in the playground. The engine seeds an EMPTY navbar by default
58+
// (DEFAULT_CHROME — an editor decides the links); this playground-only override
59+
// populates it for the dogfood. url-based items resolve without a page relation
60+
// (map-site-settings resolveNavItem), keeping the seed self-contained.
61+
header: [
62+
{
63+
__component: 'preset-organism.navbar',
64+
items: [
65+
{ label: 'Home', url: '/' },
66+
{ label: 'Docs', url: 'https://github.com/ogs-tech/press', newTab: true },
67+
],
68+
},
69+
],
5670
};
5771

5872
async function main() {

‎packages/shared/src/index.ts‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@ export interface Attr {
2323
enum?: string[];
2424
multiple?: boolean;
2525
components?: string[];
26-
/** For `type: 'component'`: the referenced component uid (e.g. `press.nav-item`). */
26+
/** For `type: 'component'`: the referenced component uid (e.g. `preset-molecule.nav-item`). */
2727
component?: string;
2828
/** For `type: 'component'`: repeatable → array on the wire (Spec §2). */
2929
repeatable?: boolean;

‎packages/web/src/plugins/cookie-consent/types.ts‎

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -23,15 +23,15 @@ export interface ConsentState {
2323
decidedAt: string;
2424
}
2525

26-
/** Raw `press.cookie-category` payload as populated by the site-setting controller. */
26+
/** Raw `preset-config.cookie-category` payload as populated by the site-setting controller. */
2727
export interface RawCookieCategory {
2828
enabled?: boolean;
2929
label?: string;
3030
description?: string;
3131
}
3232

3333
/**
34-
* Raw `press.cookie-consent` payload as populated by the site-setting
34+
* Raw `preset-config.cookie-consent` payload as populated by the site-setting
3535
* controller. EVERY field is optional: an unfilled component and an
3636
* unreachable CMS both map as if absent (the SiteSettingsData rule).
3737
*/

0 commit comments

Comments
 (0)