@bison-lab/payload-blocks 2.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +163 -0
- package/dist/cx-BKHSv3xT.mjs +17 -0
- package/dist/cx-BKHSv3xT.mjs.map +1 -0
- package/dist/index.d.mts +344 -0
- package/dist/index.d.mts.map +1 -0
- package/dist/index.mjs +677 -0
- package/dist/index.mjs.map +1 -0
- package/dist/react.d.mts +53 -0
- package/dist/react.d.mts.map +1 -0
- package/dist/react.mjs +370 -0
- package/dist/react.mjs.map +1 -0
- package/dist/rich-text.d.mts +24 -0
- package/dist/rich-text.d.mts.map +1 -0
- package/dist/rich-text.mjs +31 -0
- package/dist/rich-text.mjs.map +1 -0
- package/dist/types-BvRvDCDT.d.mts +307 -0
- package/dist/types-BvRvDCDT.d.mts.map +1 -0
- package/package.json +81 -0
package/README.md
ADDED
|
@@ -0,0 +1,163 @@
|
|
|
1
|
+
# `@bison-lab/payload-blocks`
|
|
2
|
+
|
|
3
|
+
Payload CMS block configs and renderers for the Bison Lab marketing blocks.
|
|
4
|
+
|
|
5
|
+
Install it in a Payload site and editors get the same sections `@bison-lab/ui`
|
|
6
|
+
ships as React props — showcase panels, process steps, FAQ columns, testimonial
|
|
7
|
+
masonry, NAP — as blocks they can add to a page.
|
|
8
|
+
|
|
9
|
+
```bash
|
|
10
|
+
pnpm add @bison-lab/payload-blocks
|
|
11
|
+
```
|
|
12
|
+
|
|
13
|
+
Peers: `payload` (required); `react`, `react-dom`, `@bison-lab/ui` and
|
|
14
|
+
`@payloadcms/richtext-lexical` (needed by the renderer entries, optional if you
|
|
15
|
+
only use the configs).
|
|
16
|
+
|
|
17
|
+
## Two entry points, and why
|
|
18
|
+
|
|
19
|
+
| Import | Contents | Runs where |
|
|
20
|
+
| --- | --- | --- |
|
|
21
|
+
| `@bison-lab/payload-blocks` | Block configs, field builders, row types, `resolveMedia` | Node. This is what `payload.config.ts` imports, and it touches no React. |
|
|
22
|
+
| `@bison-lab/payload-blocks/react` | Renderers, `RenderBlocks`, the rendering types | Client (`"use client"`). |
|
|
23
|
+
| `@bison-lab/payload-blocks/rich-text` | The `richText` renderer, alone | Client. Split out because it is the only thing that needs `@payloadcms/richtext-lexical`. |
|
|
24
|
+
|
|
25
|
+
The renderers are client components because the blocks they render are: every
|
|
26
|
+
`@bison-lab/ui` export is a client reference, and these blocks are interactive
|
|
27
|
+
anyway. That is also what makes `imageComponent` work — a Server Component can
|
|
28
|
+
hand a client component reference across the boundary, but not a closure.
|
|
29
|
+
|
|
30
|
+
## Wiring a site
|
|
31
|
+
|
|
32
|
+
**1. Add the blocks to a collection.**
|
|
33
|
+
|
|
34
|
+
```ts
|
|
35
|
+
import {
|
|
36
|
+
FaqColumnsBlock,
|
|
37
|
+
HeroBlock,
|
|
38
|
+
NapBlock,
|
|
39
|
+
ProcessStepsBlock,
|
|
40
|
+
RichTextBlock,
|
|
41
|
+
ShowcasePanelsBlock,
|
|
42
|
+
TestimonialMasonryBlock,
|
|
43
|
+
} from '@bison-lab/payload-blocks'
|
|
44
|
+
|
|
45
|
+
export const Pages: CollectionConfig = {
|
|
46
|
+
slug: 'pages',
|
|
47
|
+
fields: [
|
|
48
|
+
{ name: 'hero', type: 'blocks', blocks: [HeroBlock], maxRows: 1 },
|
|
49
|
+
{
|
|
50
|
+
name: 'layout',
|
|
51
|
+
type: 'blocks',
|
|
52
|
+
blocks: [
|
|
53
|
+
RichTextBlock,
|
|
54
|
+
ShowcasePanelsBlock,
|
|
55
|
+
ProcessStepsBlock,
|
|
56
|
+
FaqColumnsBlock,
|
|
57
|
+
TestimonialMasonryBlock,
|
|
58
|
+
NapBlock,
|
|
59
|
+
],
|
|
60
|
+
},
|
|
61
|
+
],
|
|
62
|
+
}
|
|
63
|
+
```
|
|
64
|
+
|
|
65
|
+
Then `payload generate:types` and `payload migrate:create`.
|
|
66
|
+
|
|
67
|
+
**2. Own the registry.**
|
|
68
|
+
|
|
69
|
+
The registry is a parameter, not an export, so the compile-time layout lock
|
|
70
|
+
stays in your site — where the generated types are:
|
|
71
|
+
|
|
72
|
+
```ts
|
|
73
|
+
import type { Page } from '@/payload-types'
|
|
74
|
+
import {
|
|
75
|
+
type BlockRegistryFor,
|
|
76
|
+
FaqColumnsBlockRenderer,
|
|
77
|
+
NapBlockRenderer,
|
|
78
|
+
ProcessStepsBlockRenderer,
|
|
79
|
+
ShowcasePanelsBlockRenderer,
|
|
80
|
+
TestimonialMasonryBlockRenderer,
|
|
81
|
+
} from '@bison-lab/payload-blocks/react'
|
|
82
|
+
import { RichTextBlockRenderer } from '@bison-lab/payload-blocks/rich-text'
|
|
83
|
+
|
|
84
|
+
type AnyBlock = NonNullable<Page['hero']>[number] | NonNullable<Page['layout']>[number]
|
|
85
|
+
|
|
86
|
+
export const blockRegistry = {
|
|
87
|
+
hero: SiteHeroRenderer, // yours; the package's is deliberately plain
|
|
88
|
+
richText: RichTextBlockRenderer,
|
|
89
|
+
showcasePanels: ShowcasePanelsBlockRenderer,
|
|
90
|
+
processSteps: ProcessStepsBlockRenderer,
|
|
91
|
+
faqColumns: FaqColumnsBlockRenderer,
|
|
92
|
+
testimonialMasonry: TestimonialMasonryBlockRenderer,
|
|
93
|
+
nap: NapBlockRenderer,
|
|
94
|
+
} satisfies BlockRegistryFor<AnyBlock>
|
|
95
|
+
```
|
|
96
|
+
|
|
97
|
+
Add a block to the collection and `satisfies` fails typecheck until it has a
|
|
98
|
+
renderer. Never widen that type to get past the error; add the entry.
|
|
99
|
+
|
|
100
|
+
**3. Render the page.**
|
|
101
|
+
|
|
102
|
+
```tsx
|
|
103
|
+
<RenderBlocks
|
|
104
|
+
blocks={[...page.hero, ...page.layout]}
|
|
105
|
+
registry={blockRegistry}
|
|
106
|
+
containerClassName={CONTAINER}
|
|
107
|
+
imageComponent={NextBlockImage}
|
|
108
|
+
/>
|
|
109
|
+
```
|
|
110
|
+
|
|
111
|
+
`containerClassName` is your site's page measure. Every renderer puts it on the
|
|
112
|
+
band wrapper and resets the library block's own `max-w-*` / `px-*` so the two
|
|
113
|
+
cannot fight.
|
|
114
|
+
|
|
115
|
+
`imageComponent` is how images get optimised. The package has no `next`
|
|
116
|
+
dependency — `next/image` needs per-site configuration this package cannot
|
|
117
|
+
supply — so a Next site writes one adapter and passes it once:
|
|
118
|
+
|
|
119
|
+
```tsx
|
|
120
|
+
'use client'
|
|
121
|
+
import Image from 'next/image'
|
|
122
|
+
import type { BlockImageProps } from '@bison-lab/payload-blocks/react'
|
|
123
|
+
|
|
124
|
+
export function NextBlockImage({ src, alt, width, height, ...rest }: BlockImageProps) {
|
|
125
|
+
if (!width || !height) return <Image src={src} alt={alt} fill {...rest} />
|
|
126
|
+
return <Image src={src} alt={alt} width={width} height={height} {...rest} />
|
|
127
|
+
}
|
|
128
|
+
```
|
|
129
|
+
|
|
130
|
+
Uploads are served from `/api/media/file/…`, so widen `next.config.ts`
|
|
131
|
+
`images.localPatterns` (or `remotePatterns`) to match before any CMS image
|
|
132
|
+
renders.
|
|
133
|
+
|
|
134
|
+
## Blocks
|
|
135
|
+
|
|
136
|
+
| Slug | Renders | Notes |
|
|
137
|
+
| --- | --- | --- |
|
|
138
|
+
| `hero` | plain markup | No `@bison-lab/ui` counterpart. Override this entry with your own. |
|
|
139
|
+
| `richText` | `RichText` (Lexical) | From `/rich-text`. |
|
|
140
|
+
| `showcasePanels` | `ShowcasePanelsBlock` | 3–6 panels, each with a required image. |
|
|
141
|
+
| `processSteps` | `ProcessStepsBlock` | 3–6 ordered steps; advances on a timer. |
|
|
142
|
+
| `faqColumns` | `FAQColumnsBlock` | Answers are plain text, not Lexical — see the config for why. |
|
|
143
|
+
| `testimonialMasonry` | `TestimonialMasonry` | Avatars fall back to initials. |
|
|
144
|
+
| `nap` | `NapBlock` + `JsonLd` | Emits schema.org `LocalBusiness`; `phoneE164` is what the `tel:` link uses. |
|
|
145
|
+
|
|
146
|
+
A row whose upload has not resolved is dropped rather than rendered empty, and a
|
|
147
|
+
block left with nothing to show renders nothing at all. Draft saves skip Payload
|
|
148
|
+
validation, so live preview genuinely hands renderers incomplete rows.
|
|
149
|
+
|
|
150
|
+
## Conventions for contributors
|
|
151
|
+
|
|
152
|
+
- **No generated types.** `src/types.ts` hand-writes each block's row shape to
|
|
153
|
+
match what Payload generates from the config beside it. Every field is
|
|
154
|
+
optional and nullable so a site's generated type is assignable to it, and no
|
|
155
|
+
interface here has an index signature — TypeScript will not assign an
|
|
156
|
+
interface to a type that does.
|
|
157
|
+
- **`src/index.ts` stays React-free.** Payload loads a site's config outside the
|
|
158
|
+
bundler, in `migrate`, `generate:types` and the admin server.
|
|
159
|
+
- **`cn()` is off limits.** It is a client-only export of `@bison-lab/ui`; use
|
|
160
|
+
the local `cx()`.
|
|
161
|
+
- **Changing a field is a schema change in every consuming site.** Update
|
|
162
|
+
`src/types.ts` and the field-name lock in `src/__tests__/configs.test.ts` in
|
|
163
|
+
the same change, and say "run `payload migrate:create`" in the changeset.
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
//#region src/cx.ts
|
|
3
|
+
/**
|
|
4
|
+
* Class joining, locally.
|
|
5
|
+
*
|
|
6
|
+
* `cn()` from `@bison-lab/ui` cannot be used here: that barrel is stamped
|
|
7
|
+
* `"use client"`, so calling it from a Server Component throws. The renderers
|
|
8
|
+
* only ever concatenate their own literals with a caller-supplied string —
|
|
9
|
+
* there are no conflicting Tailwind utilities to merge — so a join is enough.
|
|
10
|
+
*/
|
|
11
|
+
function cx(...parts) {
|
|
12
|
+
return parts.filter(Boolean).join(" ");
|
|
13
|
+
}
|
|
14
|
+
//#endregion
|
|
15
|
+
export { cx as t };
|
|
16
|
+
|
|
17
|
+
//# sourceMappingURL=cx-BKHSv3xT.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cx-BKHSv3xT.mjs","names":[],"sources":["../src/cx.ts"],"sourcesContent":["/**\n * Class joining, locally.\n *\n * `cn()` from `@bison-lab/ui` cannot be used here: that barrel is stamped\n * `\"use client\"`, so calling it from a Server Component throws. The renderers\n * only ever concatenate their own literals with a caller-supplied string —\n * there are no conflicting Tailwind utilities to merge — so a join is enough.\n */\nexport function cx(...parts: (string | false | null | undefined)[]): string {\n return parts.filter(Boolean).join(\" \");\n}\n"],"mappings":";;;;;;;;;;AAQA,SAAgB,GAAG,GAAG,OAAsD;AAC1E,QAAO,MAAM,OAAO,QAAQ,CAAC,KAAK,IAAI"}
|
package/dist/index.d.mts
ADDED
|
@@ -0,0 +1,344 @@
|
|
|
1
|
+
import { Block, CollectionSlug, Field, GroupField, UploadField } from "payload";
|
|
2
|
+
|
|
3
|
+
//#region src/blocks/hero/config.d.ts
|
|
4
|
+
/**
|
|
5
|
+
* The band a page opens with.
|
|
6
|
+
*
|
|
7
|
+
* Unlike every other block here this one has no `@bison-lab/ui` counterpart:
|
|
8
|
+
* a hero is where a site's brand is loudest, and the shipped renderer is
|
|
9
|
+
* deliberately plain markup so a site can swap in its own by overriding this
|
|
10
|
+
* one registry entry. The *fields* are the shared part — that is what makes a
|
|
11
|
+
* page portable between sites.
|
|
12
|
+
*/
|
|
13
|
+
declare const HeroBlock: Block;
|
|
14
|
+
//#endregion
|
|
15
|
+
//#region src/blocks/rich-text/config.d.ts
|
|
16
|
+
/** A prose section: one Lexical document at reading measure. */
|
|
17
|
+
declare const RichTextBlock: Block;
|
|
18
|
+
//#endregion
|
|
19
|
+
//#region src/blocks/showcase-panels/config.d.ts
|
|
20
|
+
/** Expanding panels, one per service or product line. */
|
|
21
|
+
declare const ShowcasePanelsBlock: Block;
|
|
22
|
+
//#endregion
|
|
23
|
+
//#region src/blocks/process-steps/config.d.ts
|
|
24
|
+
/** An ordered walkthrough that advances on its own. */
|
|
25
|
+
declare const ProcessStepsBlock: Block;
|
|
26
|
+
//#endregion
|
|
27
|
+
//#region src/blocks/faq-columns/config.d.ts
|
|
28
|
+
/** A sticky intro beside a column of questions. */
|
|
29
|
+
declare const FaqColumnsBlock: Block;
|
|
30
|
+
//#endregion
|
|
31
|
+
//#region src/blocks/testimonial-masonry/config.d.ts
|
|
32
|
+
/** Quotes in a masonry grid, clipped behind a fade once there are enough. */
|
|
33
|
+
declare const TestimonialMasonryBlock: Block;
|
|
34
|
+
//#endregion
|
|
35
|
+
//#region src/blocks/nap/config.d.ts
|
|
36
|
+
/**
|
|
37
|
+
* Name, address, phone — the block local SEO is graded on.
|
|
38
|
+
*
|
|
39
|
+
* The `e164` phone number is a separate field from the displayed one because
|
|
40
|
+
* `NapBlock` uses it, and only it, for the `tel:` href and the JSON-LD
|
|
41
|
+
* `telephone`. A prettified string can never silently become an unreachable
|
|
42
|
+
* link.
|
|
43
|
+
*/
|
|
44
|
+
declare const NapBlock: Block;
|
|
45
|
+
//#endregion
|
|
46
|
+
//#region src/fields/image.d.ts
|
|
47
|
+
/**
|
|
48
|
+
* Payload's `UploadField` is a union over the polymorphic (`relationTo: [...]`)
|
|
49
|
+
* and `hasMany` variants. A block image is neither, and narrowing here is what
|
|
50
|
+
* lets `imageField({ name: 'portrait' })` stay type-checked at the call site.
|
|
51
|
+
*/
|
|
52
|
+
type MediaUploadField = Extract<UploadField, {
|
|
53
|
+
hasMany?: false;
|
|
54
|
+
relationTo: CollectionSlug;
|
|
55
|
+
}>;
|
|
56
|
+
interface ImageFieldOptions extends Partial<MediaUploadField> {
|
|
57
|
+
/**
|
|
58
|
+
* The upload collection to point at. Every Bison Lab site names it `media`,
|
|
59
|
+
* but a site that does not can say so without forking the field.
|
|
60
|
+
*/
|
|
61
|
+
relationTo?: CollectionSlug;
|
|
62
|
+
}
|
|
63
|
+
/**
|
|
64
|
+
* A single image from the site's upload collection, for any block with a
|
|
65
|
+
* picture in it.
|
|
66
|
+
*
|
|
67
|
+
* Optional unless the block says otherwise: `imageField({ name: 'portrait',
|
|
68
|
+
* required: true })`. `admin` is replaced, not merged, so a block that passes
|
|
69
|
+
* its own description writes the whole thing.
|
|
70
|
+
*/
|
|
71
|
+
declare function imageField(overrides?: ImageFieldOptions): MediaUploadField;
|
|
72
|
+
//#endregion
|
|
73
|
+
//#region src/fields/link.d.ts
|
|
74
|
+
interface LinkFieldsOptions {
|
|
75
|
+
/** Require the label and destination. Defaults to `false`. */
|
|
76
|
+
required?: boolean;
|
|
77
|
+
/** Wording for the visible text field. Defaults to "Label". */
|
|
78
|
+
labelFieldLabel?: string;
|
|
79
|
+
}
|
|
80
|
+
/**
|
|
81
|
+
* The three fields a call to action is made of, unwrapped.
|
|
82
|
+
*
|
|
83
|
+
* `href` is plain text rather than a relationship to a `pages` row: a block in
|
|
84
|
+
* this package has to work on a site whose page collection is named something
|
|
85
|
+
* else, or which links out more often than in. Resolving an internal reference
|
|
86
|
+
* is the site's job.
|
|
87
|
+
*
|
|
88
|
+
* `newTab` drives `target="_blank"` *and* the matching `rel`, which is why no
|
|
89
|
+
* renderer takes one without the other.
|
|
90
|
+
*/
|
|
91
|
+
declare function linkFields({
|
|
92
|
+
required,
|
|
93
|
+
labelFieldLabel
|
|
94
|
+
}?: LinkFieldsOptions): Field[];
|
|
95
|
+
interface LinkFieldOptions extends LinkFieldsOptions {
|
|
96
|
+
/** Field name. Defaults to `link`. */
|
|
97
|
+
name?: string;
|
|
98
|
+
label?: GroupField["label"];
|
|
99
|
+
admin?: GroupField["admin"];
|
|
100
|
+
}
|
|
101
|
+
/** `linkFields()` as one named group, for a block with a single CTA. */
|
|
102
|
+
declare function linkField({
|
|
103
|
+
name,
|
|
104
|
+
label,
|
|
105
|
+
admin,
|
|
106
|
+
...rest
|
|
107
|
+
}?: LinkFieldOptions): GroupField;
|
|
108
|
+
/** The shape `linkField`/`linkFields` produce once Payload generates types. */
|
|
109
|
+
interface LinkValue {
|
|
110
|
+
label?: string | null;
|
|
111
|
+
href?: string | null;
|
|
112
|
+
newTab?: boolean | null;
|
|
113
|
+
}
|
|
114
|
+
//#endregion
|
|
115
|
+
//#region src/fields/heading.d.ts
|
|
116
|
+
interface HeadingFieldsOptions {
|
|
117
|
+
/** Require the section heading. Defaults to `true`. */
|
|
118
|
+
required?: boolean;
|
|
119
|
+
/** Description shown under the eyebrow input. */
|
|
120
|
+
eyebrowDescription?: string;
|
|
121
|
+
}
|
|
122
|
+
/**
|
|
123
|
+
* The eyebrow / title / description trio every marketing band opens with.
|
|
124
|
+
*
|
|
125
|
+
* They are three top-level fields rather than a group: editors read a section
|
|
126
|
+
* heading as the first thing in the block, and burying it one collapse deep
|
|
127
|
+
* puts the least-optional copy behind a click. The field names match the
|
|
128
|
+
* `@bison-lab/ui` prop names so the renderers stay a pass-through.
|
|
129
|
+
*/
|
|
130
|
+
declare function headingFields({
|
|
131
|
+
required,
|
|
132
|
+
eyebrowDescription
|
|
133
|
+
}?: HeadingFieldsOptions): Field[];
|
|
134
|
+
//#endregion
|
|
135
|
+
//#region src/media.d.ts
|
|
136
|
+
/**
|
|
137
|
+
* The upload side of the boundary.
|
|
138
|
+
*
|
|
139
|
+
* A Payload upload field holds either the row's id or, once depth resolves it,
|
|
140
|
+
* the whole document. Neither shape can be imported from here: `Media` is
|
|
141
|
+
* generated per site, and this package must never reach for a site's
|
|
142
|
+
* `payload-types`. So the doc is described structurally, and every renderer
|
|
143
|
+
* goes through `resolveMedia` rather than reading `.url` itself.
|
|
144
|
+
*/
|
|
145
|
+
/**
|
|
146
|
+
* The subset of a Payload upload document a block renderer actually reads.
|
|
147
|
+
* Every site's generated `Media` interface is assignable to this, whatever
|
|
148
|
+
* else it carries.
|
|
149
|
+
*
|
|
150
|
+
* Deliberately no index signature: TypeScript refuses to assign an interface
|
|
151
|
+
* to a type with one, and a site's generated `Media` is always an interface.
|
|
152
|
+
* An index signature here would break exactly the structural match this type
|
|
153
|
+
* exists to provide.
|
|
154
|
+
*/
|
|
155
|
+
interface MediaDoc {
|
|
156
|
+
url?: string | null;
|
|
157
|
+
alt?: string | null;
|
|
158
|
+
width?: number | null;
|
|
159
|
+
height?: number | null;
|
|
160
|
+
}
|
|
161
|
+
/** What an upload field holds before and after `depth` populates it. */
|
|
162
|
+
type MediaValue = number | string | MediaDoc | null | undefined;
|
|
163
|
+
/** A resolved image, in the shape every `@bison-lab/ui` block asks for. */
|
|
164
|
+
interface ResolvedMedia {
|
|
165
|
+
src: string;
|
|
166
|
+
alt: string;
|
|
167
|
+
width?: number;
|
|
168
|
+
height?: number;
|
|
169
|
+
}
|
|
170
|
+
/**
|
|
171
|
+
* Narrows an upload value to something renderable, or `undefined`.
|
|
172
|
+
*
|
|
173
|
+
* `undefined` covers three cases a renderer must treat identically: the field
|
|
174
|
+
* is empty, `depth: 0` left it as a bare id, or the document exists but has no
|
|
175
|
+
* `url` yet (an upload mid-flight). A renderer that gets `undefined` omits the
|
|
176
|
+
* image rather than emitting a broken `<img>`.
|
|
177
|
+
*
|
|
178
|
+
* `alt` is always a string: the media collection requires it, but a draft saved
|
|
179
|
+
* before that validation ran can still reach a renderer, and an `alt` of
|
|
180
|
+
* `undefined` would silently drop the attribute entirely.
|
|
181
|
+
*/
|
|
182
|
+
declare function resolveMedia(value: MediaValue): ResolvedMedia | undefined;
|
|
183
|
+
//#endregion
|
|
184
|
+
//#region src/types.d.ts
|
|
185
|
+
/**
|
|
186
|
+
* The data shape of every block in this package, hand-written.
|
|
187
|
+
*
|
|
188
|
+
* A package cannot import a site's `payload-types`: those are generated per
|
|
189
|
+
* site, from that site's own config. So each block's row shape is written out
|
|
190
|
+
* here to match what Payload generates from the config next to it, and a
|
|
191
|
+
* site's generated types then match *structurally* — no import, no adapter.
|
|
192
|
+
*
|
|
193
|
+
* Two conventions make that match reliable:
|
|
194
|
+
*
|
|
195
|
+
* 1. **Everything is optional and nullable**, `blockType` aside. A generated
|
|
196
|
+
* `title: string` is assignable to `title?: string | null`, never the other
|
|
197
|
+
* way round, so the permissive direction is the only safe one. It is also
|
|
198
|
+
* the honest one: Payload skips validation on draft saves, so a live-preview
|
|
199
|
+
* render genuinely can receive a row with its required fields still empty.
|
|
200
|
+
* Renderers guard rather than assume.
|
|
201
|
+
* 2. **No index signatures.** TypeScript will not assign an interface to a type
|
|
202
|
+
* that has one, and a generated block type is always an interface.
|
|
203
|
+
*
|
|
204
|
+
* The field-name lists in `src/__tests__/configs.test.ts` are the lock between
|
|
205
|
+
* a config and its interface here: rename a field and that test fails.
|
|
206
|
+
*/
|
|
207
|
+
/** The tail Payload appends to every block row. */
|
|
208
|
+
interface BlockRow<T extends string> {
|
|
209
|
+
id?: string | null;
|
|
210
|
+
blockName?: string | null;
|
|
211
|
+
blockType: T;
|
|
212
|
+
}
|
|
213
|
+
/**
|
|
214
|
+
* A Lexical document, structurally. The generated type carries an index
|
|
215
|
+
* signature and a narrower `format` union; both are assignable to this.
|
|
216
|
+
*/
|
|
217
|
+
interface RichTextContent {
|
|
218
|
+
root: {
|
|
219
|
+
type: string;
|
|
220
|
+
children: unknown[];
|
|
221
|
+
direction: ("ltr" | "rtl") | null;
|
|
222
|
+
format: string;
|
|
223
|
+
indent: number;
|
|
224
|
+
version: number;
|
|
225
|
+
};
|
|
226
|
+
}
|
|
227
|
+
interface HeroBlockData extends BlockRow<"hero"> {
|
|
228
|
+
eyebrow?: string | null;
|
|
229
|
+
heading?: string | null;
|
|
230
|
+
body?: string | null;
|
|
231
|
+
tone?: ("sweep" | "dark" | "light") | null;
|
|
232
|
+
image?: MediaValue;
|
|
233
|
+
links?: LinkValue[] | null;
|
|
234
|
+
}
|
|
235
|
+
interface RichTextBlockData extends BlockRow<"richText"> {
|
|
236
|
+
content?: RichTextContent | null;
|
|
237
|
+
}
|
|
238
|
+
interface ShowcasePanelsItemData {
|
|
239
|
+
title?: string | null;
|
|
240
|
+
summary?: string | null;
|
|
241
|
+
image?: MediaValue;
|
|
242
|
+
href?: string | null;
|
|
243
|
+
numeral?: string | null;
|
|
244
|
+
id?: string | null;
|
|
245
|
+
}
|
|
246
|
+
interface ShowcasePanelsBlockData extends BlockRow<"showcasePanels"> {
|
|
247
|
+
items?: ShowcasePanelsItemData[] | null;
|
|
248
|
+
watermark?: string | null;
|
|
249
|
+
spineVariant?: ("numbered" | "volume" | "minimal") | null;
|
|
250
|
+
defaultActiveIndex?: number | null;
|
|
251
|
+
ariaLabel?: string | null;
|
|
252
|
+
labels?: {
|
|
253
|
+
selected?: string | null;
|
|
254
|
+
preview?: string | null;
|
|
255
|
+
};
|
|
256
|
+
}
|
|
257
|
+
interface ProcessStepsItemData {
|
|
258
|
+
title?: string | null;
|
|
259
|
+
description?: string | null;
|
|
260
|
+
image?: MediaValue;
|
|
261
|
+
step?: number | null;
|
|
262
|
+
id?: string | null;
|
|
263
|
+
}
|
|
264
|
+
interface ProcessStepsBlockData extends BlockRow<"processSteps"> {
|
|
265
|
+
items?: ProcessStepsItemData[] | null;
|
|
266
|
+
defaultActiveIndex?: number | null;
|
|
267
|
+
autoAdvance?: boolean | null;
|
|
268
|
+
autoAdvanceDuration?: number | null;
|
|
269
|
+
pauseOnHover?: boolean | null;
|
|
270
|
+
ariaLabel?: string | null;
|
|
271
|
+
labels?: {
|
|
272
|
+
pause?: string | null;
|
|
273
|
+
resume?: string | null;
|
|
274
|
+
};
|
|
275
|
+
}
|
|
276
|
+
interface FaqColumnsItemData {
|
|
277
|
+
question?: string | null;
|
|
278
|
+
/** A textarea, not a Lexical document — see the block's config for why. */
|
|
279
|
+
answer?: string | null;
|
|
280
|
+
id?: string | null;
|
|
281
|
+
}
|
|
282
|
+
interface FaqColumnsBlockData extends BlockRow<"faqColumns"> {
|
|
283
|
+
eyebrow?: string | null;
|
|
284
|
+
title?: string | null;
|
|
285
|
+
description?: string | null;
|
|
286
|
+
items?: FaqColumnsItemData[] | null;
|
|
287
|
+
cta?: {
|
|
288
|
+
title?: string | null;
|
|
289
|
+
linkText?: string | null;
|
|
290
|
+
href?: string | null;
|
|
291
|
+
newTab?: boolean | null;
|
|
292
|
+
};
|
|
293
|
+
sticky?: boolean | null;
|
|
294
|
+
type?: ("single" | "multiple") | null;
|
|
295
|
+
collapsible?: boolean | null;
|
|
296
|
+
}
|
|
297
|
+
interface TestimonialMasonryItemData {
|
|
298
|
+
content?: string | null;
|
|
299
|
+
author?: {
|
|
300
|
+
name?: string | null;
|
|
301
|
+
title?: string | null;
|
|
302
|
+
avatar?: MediaValue;
|
|
303
|
+
};
|
|
304
|
+
id?: string | null;
|
|
305
|
+
}
|
|
306
|
+
interface TestimonialMasonryBlockData extends BlockRow<"testimonialMasonry"> {
|
|
307
|
+
eyebrow?: string | null;
|
|
308
|
+
title?: string | null;
|
|
309
|
+
description?: string | null;
|
|
310
|
+
items?: TestimonialMasonryItemData[] | null;
|
|
311
|
+
link?: LinkValue;
|
|
312
|
+
minItemsForFade?: number | null;
|
|
313
|
+
maxVisibleRows?: number | null;
|
|
314
|
+
}
|
|
315
|
+
interface NapDepartmentData {
|
|
316
|
+
name?: string | null;
|
|
317
|
+
departmentType?: string | null;
|
|
318
|
+
phoneE164?: string | null;
|
|
319
|
+
phoneDisplay?: string | null;
|
|
320
|
+
id?: string | null;
|
|
321
|
+
}
|
|
322
|
+
interface NapBlockData extends BlockRow<"nap"> {
|
|
323
|
+
businessName?: string | null;
|
|
324
|
+
businessType?: string | null;
|
|
325
|
+
address?: {
|
|
326
|
+
streetAddress?: string | null;
|
|
327
|
+
addressLocality?: string | null;
|
|
328
|
+
addressRegion?: string | null;
|
|
329
|
+
postalCode?: string | null;
|
|
330
|
+
addressCountry?: string | null;
|
|
331
|
+
};
|
|
332
|
+
departments?: NapDepartmentData[] | null;
|
|
333
|
+
url?: string | null;
|
|
334
|
+
showName?: boolean | null;
|
|
335
|
+
headingLevel?: ("h2" | "h3" | "h4") | null;
|
|
336
|
+
emitJsonLd?: boolean | null;
|
|
337
|
+
}
|
|
338
|
+
/** Every block this package ships, as one union. */
|
|
339
|
+
type BisonBlockData = HeroBlockData | RichTextBlockData | ShowcasePanelsBlockData | ProcessStepsBlockData | FaqColumnsBlockData | TestimonialMasonryBlockData | NapBlockData;
|
|
340
|
+
/** The `blockType` of every block this package ships. */
|
|
341
|
+
type BisonBlockType = BisonBlockData["blockType"];
|
|
342
|
+
//#endregion
|
|
343
|
+
export { type BisonBlockData, type BisonBlockType, FaqColumnsBlock, type FaqColumnsBlockData, type FaqColumnsItemData, type HeadingFieldsOptions, HeroBlock, type HeroBlockData, type ImageFieldOptions, type LinkFieldOptions, type LinkFieldsOptions, type LinkValue, type MediaDoc, type MediaValue, NapBlock, type NapBlockData, type NapDepartmentData, ProcessStepsBlock, type ProcessStepsBlockData, type ProcessStepsItemData, type ResolvedMedia, RichTextBlock, type RichTextBlockData, type RichTextContent, ShowcasePanelsBlock, type ShowcasePanelsBlockData, type ShowcasePanelsItemData, TestimonialMasonryBlock, type TestimonialMasonryBlockData, type TestimonialMasonryItemData, headingFields, imageField, linkField, linkFields, resolveMedia };
|
|
344
|
+
//# sourceMappingURL=index.d.mts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.mts","names":[],"sources":["../src/blocks/hero/config.ts","../src/blocks/rich-text/config.ts","../src/blocks/showcase-panels/config.ts","../src/blocks/process-steps/config.ts","../src/blocks/faq-columns/config.ts","../src/blocks/testimonial-masonry/config.ts","../src/blocks/nap/config.ts","../src/fields/image.ts","../src/fields/link.ts","../src/fields/heading.ts","../src/media.ts","../src/types.ts"],"mappings":"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"}
|