bsmnt 0.13.0 → 0.14.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/dist/modules/features/cms/sanity-pagebuilder/config.d.ts.map +1 -1
- package/dist/modules/features/cms/sanity-pagebuilder/config.js +1 -0
- package/dist/modules/features/cms/sanity-pagebuilder/config.js.map +1 -1
- package/dist/modules/features/cms/sanity-pagebuilder-cache/config.d.ts.map +1 -1
- package/dist/modules/features/cms/sanity-pagebuilder-cache/config.js +1 -0
- package/dist/modules/features/cms/sanity-pagebuilder-cache/config.js.map +1 -1
- package/package.json +1 -1
- package/src/agent-skills/ashby-pagebuilder-block/SKILL.md +29 -11
- package/src/agent-skills/hubspot-pagebuilder-block/SKILL.md +31 -12
- package/src/agent-skills/page-builder-block/SKILL.md +26 -13
- package/src/modules/features/cms/sanity-pagebuilder/files/app/api/revalidate/route.ts +2 -2
- package/src/modules/features/cms/sanity-pagebuilder/files/components/sanity/rich-text.tsx +1 -1
- package/src/modules/features/cms/sanity-pagebuilder/files/lib/integrations/sanity/components/block-actions-item.tsx +2 -2
- package/src/modules/features/cms/sanity-pagebuilder/files/lib/integrations/sanity/components/component-preview-frame.tsx +124 -0
- package/src/modules/features/cms/sanity-pagebuilder/files/lib/integrations/sanity/components/component-preview-pane.tsx +25 -0
- package/src/modules/features/cms/sanity-pagebuilder/files/lib/integrations/sanity/components/page-builder-input.tsx +3 -26
- package/src/modules/features/cms/sanity-pagebuilder/files/lib/integrations/sanity/components/page-builder-insert-menu.tsx +121 -93
- package/src/modules/features/cms/sanity-pagebuilder/files/lib/integrations/sanity/icons.ts +2 -2
- package/src/modules/features/cms/sanity-pagebuilder/files/lib/integrations/sanity/page-builder-config.ts +22 -50
- package/src/modules/features/cms/sanity-pagebuilder/files/lib/integrations/sanity/presentation.ts +1 -18
- package/src/modules/features/cms/sanity-pagebuilder/files/lib/integrations/sanity/queries.ts +56 -64
- package/src/modules/features/cms/sanity-pagebuilder/files/lib/integrations/sanity/sanity.config.ts +4 -8
- package/src/modules/features/cms/sanity-pagebuilder/files/lib/integrations/sanity/schemas/components/index.ts +0 -1
- package/src/modules/features/cms/sanity-pagebuilder/files/lib/integrations/sanity/schemas/components/reusable/blog-content.ts +2 -2
- package/src/modules/features/cms/sanity-pagebuilder/files/lib/integrations/sanity/schemas/index.ts +1 -4
- package/src/modules/features/cms/sanity-pagebuilder/files/lib/integrations/sanity/schemas/shared/block.ts +4 -4
- package/src/modules/features/cms/sanity-pagebuilder/files/lib/integrations/sanity/schemas/shared/page-builder.ts +4 -18
- package/src/modules/features/cms/sanity-pagebuilder/files/lib/integrations/sanity/schemas/shared/page.ts +11 -37
- package/src/modules/features/cms/sanity-pagebuilder/files/lib/integrations/sanity/singletons.ts +0 -16
- package/src/modules/features/cms/sanity-pagebuilder/files/lib/integrations/sanity/structure.ts +35 -33
- package/src/modules/features/cms/sanity-pagebuilder/files/lib/utils/studio-embed.ts +22 -0
- package/src/modules/features/cms/sanity-pagebuilder-cache/files/app/api/revalidate/route.ts +2 -2
- package/src/modules/features/cms/sanity-pagebuilder-cache/files/components/sanity/rich-text.tsx +1 -1
- package/src/modules/features/cms/sanity-pagebuilder-cache/files/lib/integrations/sanity/components/block-actions-item.tsx +2 -2
- package/src/modules/features/cms/sanity-pagebuilder-cache/files/lib/integrations/sanity/components/component-preview-frame.tsx +124 -0
- package/src/modules/features/cms/sanity-pagebuilder-cache/files/lib/integrations/sanity/components/component-preview-pane.tsx +25 -0
- package/src/modules/features/cms/sanity-pagebuilder-cache/files/lib/integrations/sanity/components/page-builder-input.tsx +3 -26
- package/src/modules/features/cms/sanity-pagebuilder-cache/files/lib/integrations/sanity/components/page-builder-insert-menu.tsx +121 -93
- package/src/modules/features/cms/sanity-pagebuilder-cache/files/lib/integrations/sanity/icons.ts +2 -2
- package/src/modules/features/cms/sanity-pagebuilder-cache/files/lib/integrations/sanity/page-builder-config.ts +22 -50
- package/src/modules/features/cms/sanity-pagebuilder-cache/files/lib/integrations/sanity/presentation.ts +1 -18
- package/src/modules/features/cms/sanity-pagebuilder-cache/files/lib/integrations/sanity/queries.ts +56 -64
- package/src/modules/features/cms/sanity-pagebuilder-cache/files/lib/integrations/sanity/sanity.config.ts +4 -8
- package/src/modules/features/cms/sanity-pagebuilder-cache/files/lib/integrations/sanity/schemas/components/index.ts +0 -1
- package/src/modules/features/cms/sanity-pagebuilder-cache/files/lib/integrations/sanity/schemas/components/reusable/blog-content.ts +2 -2
- package/src/modules/features/cms/sanity-pagebuilder-cache/files/lib/integrations/sanity/schemas/index.ts +1 -4
- package/src/modules/features/cms/sanity-pagebuilder-cache/files/lib/integrations/sanity/schemas/shared/block.ts +4 -4
- package/src/modules/features/cms/sanity-pagebuilder-cache/files/lib/integrations/sanity/schemas/shared/page-builder.ts +4 -18
- package/src/modules/features/cms/sanity-pagebuilder-cache/files/lib/integrations/sanity/schemas/shared/page.ts +11 -37
- package/src/modules/features/cms/sanity-pagebuilder-cache/files/lib/integrations/sanity/singletons.ts +0 -16
- package/src/modules/features/cms/sanity-pagebuilder-cache/files/lib/integrations/sanity/structure.ts +35 -33
- package/src/modules/features/cms/sanity-pagebuilder-cache/files/lib/utils/studio-embed.ts +22 -0
- package/src/modules/features/forms/hubspot/files/_sanity-adapter/form-block.ts +4 -10
- package/src/modules/features/forms/hubspot/files/lib/integrations/hubspot/README.md +10 -5
- package/src/modules/features/jobs/ashby/files/_sanity-adapter/job-board-block.ts +0 -7
- package/src/modules/features/jobs/ashby/files/lib/integrations/ashby/README.md +11 -5
- package/src/templates/next-default/lib/utils/README.md +1 -0
- package/src/templates/next-default/lib/utils/image-sizes.ts +64 -25
- package/src/templates/next-experiments/lib/utils/README.md +1 -0
- package/src/templates/next-experiments/lib/utils/image-sizes.ts +64 -25
- package/src/templates/next-pagebuilder/AGENTS.md +19 -7
- package/src/templates/next-pagebuilder/README.md +15 -3
- package/src/templates/next-pagebuilder/app/actions/unlock-gated-content.ts +5 -4
- package/src/templates/next-pagebuilder/app/components/page.tsx +81 -0
- package/src/templates/next-pagebuilder/components/page-builder/components/gated-content/index.tsx +8 -3
- package/src/templates/next-pagebuilder/components/page-builder/library.ts +183 -0
- package/src/templates/next-pagebuilder/components/page-builder/registry.tsx +4 -1
- package/src/templates/next-pagebuilder/components/page-builder/renderer.tsx +3 -1
- package/src/templates/next-pagebuilder/components/page-builder/stage.tsx +10 -0
- package/src/templates/next-pagebuilder/components/page-document/index.tsx +2 -1
- package/src/templates/next-pagebuilder/lib/integrations/sanity/sanity.types.ts +139 -271
- package/src/templates/next-pagebuilder/lib/utils/image-sizes.ts +64 -25
- package/src/templates/next-pagebuilder-cache/AGENTS.md +19 -7
- package/src/templates/next-pagebuilder-cache/README.md +15 -3
- package/src/templates/next-pagebuilder-cache/app/actions/unlock-gated-content.ts +5 -4
- package/src/templates/next-pagebuilder-cache/app/components/page.tsx +91 -0
- package/src/templates/next-pagebuilder-cache/components/page-builder/components/gated-content/index.tsx +8 -3
- package/src/templates/next-pagebuilder-cache/components/page-builder/library.ts +183 -0
- package/src/templates/next-pagebuilder-cache/components/page-builder/registry.tsx +4 -1
- package/src/templates/next-pagebuilder-cache/components/page-builder/renderer.tsx +3 -1
- package/src/templates/next-pagebuilder-cache/components/page-builder/stage.tsx +10 -0
- package/src/templates/next-pagebuilder-cache/components/page-document/index.tsx +2 -1
- package/src/templates/next-pagebuilder-cache/lib/integrations/sanity/sanity.types.ts +139 -271
- package/src/templates/next-pagebuilder-cache/lib/utils/image-sizes.ts +64 -25
- package/src/templates/next-webgl/lib/utils/README.md +1 -0
- package/src/templates/next-webgl/lib/utils/image-sizes.ts +64 -25
- package/src/modules/features/cms/sanity-pagebuilder/files/lib/integrations/sanity/components/use-studio-preview-urls.ts +0 -62
- package/src/modules/features/cms/sanity-pagebuilder/files/lib/integrations/sanity/schemas/components/studio-preview.ts +0 -37
- package/src/modules/features/cms/sanity-pagebuilder-cache/files/lib/integrations/sanity/components/use-studio-preview-urls.ts +0 -62
- package/src/modules/features/cms/sanity-pagebuilder-cache/files/lib/integrations/sanity/schemas/components/studio-preview.ts +0 -37
|
@@ -12,6 +12,11 @@ import {
|
|
|
12
12
|
} from "@sanity/ui";
|
|
13
13
|
import { useMemo, useState } from "react";
|
|
14
14
|
import type { ArrayInputFunctionsProps, ArraySchemaType } from "sanity";
|
|
15
|
+
import {
|
|
16
|
+
getComponentPreviewPath,
|
|
17
|
+
getLibraryEntry,
|
|
18
|
+
} from "@/components/page-builder/library";
|
|
19
|
+
import { ComponentPreviewFrame } from "./component-preview-frame";
|
|
15
20
|
|
|
16
21
|
type ArrayItem = { _key: string };
|
|
17
22
|
type MemberSchemaType = ArraySchemaType["of"][number];
|
|
@@ -24,18 +29,22 @@ type InsertMenuSection = {
|
|
|
24
29
|
members: MemberSchemaType[];
|
|
25
30
|
};
|
|
26
31
|
|
|
27
|
-
const
|
|
28
|
-
const
|
|
32
|
+
const DIALOG_HEIGHT = "min(70vh, 42rem)";
|
|
33
|
+
const CHOICE_LIST_WIDTH = 260;
|
|
29
34
|
|
|
30
35
|
const memberTitle = (member: MemberSchemaType) => member.title ?? member.name;
|
|
31
36
|
|
|
32
|
-
function
|
|
37
|
+
function ChoiceRow({
|
|
38
|
+
active,
|
|
33
39
|
member,
|
|
34
|
-
|
|
40
|
+
notes,
|
|
41
|
+
onAdd,
|
|
35
42
|
onSelect,
|
|
36
43
|
}: {
|
|
44
|
+
active: boolean;
|
|
37
45
|
member: MemberSchemaType;
|
|
38
|
-
|
|
46
|
+
notes: string | undefined;
|
|
47
|
+
onAdd: () => void;
|
|
39
48
|
onSelect: () => void;
|
|
40
49
|
}) {
|
|
41
50
|
const Icon = member.icon;
|
|
@@ -43,63 +52,42 @@ function BlockTile({
|
|
|
43
52
|
return (
|
|
44
53
|
<Card
|
|
45
54
|
as="button"
|
|
46
|
-
border
|
|
47
55
|
onClick={onSelect}
|
|
48
|
-
|
|
49
|
-
padding={
|
|
56
|
+
onDoubleClick={onAdd}
|
|
57
|
+
padding={2}
|
|
58
|
+
pressed={active}
|
|
50
59
|
radius={2}
|
|
51
60
|
style={{ cursor: "pointer", textAlign: "left", width: "100%" }}
|
|
61
|
+
tone={active ? "primary" : "default"}
|
|
52
62
|
type="button"
|
|
53
63
|
>
|
|
54
|
-
<
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
{previewUrl ? (
|
|
63
|
-
// biome-ignore lint/performance/noImgElement: Studio-only CMS asset
|
|
64
|
-
<img
|
|
65
|
-
alt=""
|
|
66
|
-
src={`${previewUrl}?w=640&fit=max&auto=format`}
|
|
67
|
-
style={{
|
|
68
|
-
height: "100%",
|
|
69
|
-
inset: 0,
|
|
70
|
-
objectFit: "contain",
|
|
71
|
-
position: "absolute",
|
|
72
|
-
width: "100%",
|
|
73
|
-
}}
|
|
74
|
-
/>
|
|
75
|
-
) : (
|
|
76
|
-
<Flex
|
|
77
|
-
align="center"
|
|
78
|
-
justify="center"
|
|
79
|
-
style={{ inset: 0, position: "absolute" }}
|
|
80
|
-
>
|
|
81
|
-
{Icon ? <Icon /> : null}
|
|
82
|
-
</Flex>
|
|
83
|
-
)}
|
|
84
|
-
</Box>
|
|
85
|
-
<Box padding={2}>
|
|
86
|
-
<Text size={1} textOverflow="ellipsis" weight="medium">
|
|
64
|
+
<Flex align="flex-start" gap={3}>
|
|
65
|
+
{Icon ? (
|
|
66
|
+
<Text size={2}>
|
|
67
|
+
<Icon />
|
|
68
|
+
</Text>
|
|
69
|
+
) : null}
|
|
70
|
+
<Stack flex={1} space={2}>
|
|
71
|
+
<Text size={1} weight="medium">
|
|
87
72
|
{memberTitle(member)}
|
|
88
73
|
</Text>
|
|
89
|
-
|
|
90
|
-
|
|
74
|
+
{notes ? (
|
|
75
|
+
<Text muted size={0} style={{ lineHeight: 1.4 }}>
|
|
76
|
+
{notes}
|
|
77
|
+
</Text>
|
|
78
|
+
) : null}
|
|
79
|
+
</Stack>
|
|
80
|
+
</Flex>
|
|
91
81
|
</Card>
|
|
92
82
|
);
|
|
93
83
|
}
|
|
94
84
|
|
|
95
85
|
function InsertMenuDialog({
|
|
96
86
|
sections,
|
|
97
|
-
previewImageUrl,
|
|
98
87
|
onSelect,
|
|
99
88
|
onClose,
|
|
100
89
|
}: {
|
|
101
90
|
sections: InsertMenuSection[];
|
|
102
|
-
previewImageUrl: ((schemaTypeName: string) => string | undefined) | undefined;
|
|
103
91
|
onSelect: (member: MemberSchemaType) => void;
|
|
104
92
|
onClose: () => void;
|
|
105
93
|
}) {
|
|
@@ -118,60 +106,108 @@ function InsertMenuDialog({
|
|
|
118
106
|
.filter((section) => section.members.length > 0);
|
|
119
107
|
}, [search, sections]);
|
|
120
108
|
|
|
109
|
+
const visibleMembers = visibleSections.flatMap((section) => section.members);
|
|
110
|
+
const [selectedName, setSelectedName] = useState(
|
|
111
|
+
() => visibleMembers[0]?.name,
|
|
112
|
+
);
|
|
113
|
+
|
|
114
|
+
const selected =
|
|
115
|
+
visibleMembers.find((member) => member.name === selectedName) ??
|
|
116
|
+
visibleMembers[0];
|
|
117
|
+
|
|
118
|
+
const selectedEntry = selected ? getLibraryEntry(selected.name) : null;
|
|
119
|
+
|
|
121
120
|
return (
|
|
122
121
|
<Dialog
|
|
122
|
+
footer={
|
|
123
|
+
<Flex gap={2} justify="flex-end" padding={3}>
|
|
124
|
+
<Button mode="bleed" onClick={onClose} text="Cancel" />
|
|
125
|
+
<Button
|
|
126
|
+
disabled={!selected}
|
|
127
|
+
onClick={() => selected && onSelect(selected)}
|
|
128
|
+
text="Add component"
|
|
129
|
+
tone="primary"
|
|
130
|
+
/>
|
|
131
|
+
</Flex>
|
|
132
|
+
}
|
|
123
133
|
header="Components"
|
|
124
134
|
id="page-builder-insert"
|
|
125
135
|
onClose={onClose}
|
|
126
136
|
open
|
|
127
|
-
width={
|
|
137
|
+
width={4}
|
|
128
138
|
>
|
|
129
|
-
<
|
|
130
|
-
<
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
139
|
+
<Flex gap={3} padding={3} style={{ height: DIALOG_HEIGHT }}>
|
|
140
|
+
<Stack
|
|
141
|
+
space={3}
|
|
142
|
+
style={{ flex: `0 0 ${CHOICE_LIST_WIDTH}px`, minWidth: 0 }}
|
|
143
|
+
>
|
|
144
|
+
<TextInput
|
|
145
|
+
autoFocus
|
|
146
|
+
icon={SearchIcon}
|
|
147
|
+
onChange={(event) => setSearch(event.currentTarget.value)}
|
|
148
|
+
placeholder="Search components…"
|
|
149
|
+
value={search}
|
|
150
|
+
/>
|
|
151
|
+
<Box style={{ flex: 1, overflowY: "auto" }}>
|
|
152
|
+
{visibleSections.length === 0 ? (
|
|
153
|
+
<Text muted size={1}>
|
|
154
|
+
No components match “{search}”.
|
|
155
|
+
</Text>
|
|
156
|
+
) : (
|
|
157
|
+
<Stack space={4}>
|
|
158
|
+
{visibleSections.map((section) => (
|
|
159
|
+
<Stack key={section.name} space={2}>
|
|
160
|
+
<Text muted size={0} weight="semibold">
|
|
161
|
+
{section.title.toUpperCase()}
|
|
162
|
+
</Text>
|
|
163
|
+
<Stack space={1}>
|
|
164
|
+
{section.members.map((member) => (
|
|
165
|
+
<ChoiceRow
|
|
166
|
+
active={member.name === selected?.name}
|
|
167
|
+
key={member.name}
|
|
168
|
+
member={member}
|
|
169
|
+
notes={getLibraryEntry(member.name)?.notes}
|
|
170
|
+
onAdd={() => onSelect(member)}
|
|
171
|
+
onSelect={() => setSelectedName(member.name)}
|
|
172
|
+
/>
|
|
173
|
+
))}
|
|
174
|
+
</Stack>
|
|
175
|
+
</Stack>
|
|
176
|
+
))}
|
|
177
|
+
</Stack>
|
|
178
|
+
)}
|
|
179
|
+
</Box>
|
|
180
|
+
</Stack>
|
|
181
|
+
|
|
182
|
+
<Card
|
|
183
|
+
border
|
|
184
|
+
flex={1}
|
|
185
|
+
radius={2}
|
|
186
|
+
style={{ overflow: "hidden" }}
|
|
187
|
+
tone="transparent"
|
|
188
|
+
>
|
|
189
|
+
{selected && selectedEntry ? (
|
|
190
|
+
<ComponentPreviewFrame
|
|
191
|
+
key={selected.name}
|
|
192
|
+
notes={selectedEntry.notes}
|
|
193
|
+
path={getComponentPreviewPath(selected.name)}
|
|
194
|
+
/>
|
|
142
195
|
) : (
|
|
143
|
-
<
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
</Text>
|
|
149
|
-
<Grid columns={[2, 3, 4]} gap={3}>
|
|
150
|
-
{section.members.map((member) => (
|
|
151
|
-
<BlockTile
|
|
152
|
-
key={member.name}
|
|
153
|
-
member={member}
|
|
154
|
-
onSelect={() => onSelect(member)}
|
|
155
|
-
previewUrl={previewImageUrl?.(member.name)}
|
|
156
|
-
/>
|
|
157
|
-
))}
|
|
158
|
-
</Grid>
|
|
159
|
-
</Stack>
|
|
160
|
-
))}
|
|
161
|
-
</Stack>
|
|
196
|
+
<Flex align="center" height="fill" justify="center" padding={4}>
|
|
197
|
+
<Text muted size={1}>
|
|
198
|
+
No preview for this component yet.
|
|
199
|
+
</Text>
|
|
200
|
+
</Flex>
|
|
162
201
|
)}
|
|
163
|
-
</
|
|
164
|
-
</
|
|
202
|
+
</Card>
|
|
203
|
+
</Flex>
|
|
165
204
|
</Dialog>
|
|
166
205
|
);
|
|
167
206
|
}
|
|
168
207
|
|
|
169
208
|
/**
|
|
170
|
-
* Pass as `arrayFunctions`.
|
|
171
|
-
*
|
|
172
|
-
*
|
|
173
|
-
* Replaces the built-in popover, which is anchored to the array grid element and
|
|
174
|
-
* so clips on page scroll and resizes when switching tabs.
|
|
209
|
+
* Pass as `arrayFunctions`. Replaces the built-in popover, which is anchored to
|
|
210
|
+
* the array grid element and so clips on page scroll.
|
|
175
211
|
*/
|
|
176
212
|
export function PageBuilderInsertMenu(
|
|
177
213
|
props: ArrayInputFunctionsProps<ArrayItem, ArraySchemaType>,
|
|
@@ -199,13 +235,6 @@ export function PageBuilderInsertMenu(
|
|
|
199
235
|
.filter((section) => section.members.length > 0);
|
|
200
236
|
}, [members, insertMenu]);
|
|
201
237
|
|
|
202
|
-
const previewImageUrl = useMemo(() => {
|
|
203
|
-
const gridView = insertMenu?.views?.find((view) => view.name === "grid");
|
|
204
|
-
return gridView && "previewImageUrl" in gridView
|
|
205
|
-
? gridView.previewImageUrl
|
|
206
|
-
: undefined;
|
|
207
|
-
}, [insertMenu]);
|
|
208
|
-
|
|
209
238
|
const insert = (member: MemberSchemaType) => {
|
|
210
239
|
onItemAppend((onValueCreate as unknown as CreateItem)(member));
|
|
211
240
|
setOpen(false);
|
|
@@ -233,7 +262,6 @@ export function PageBuilderInsertMenu(
|
|
|
233
262
|
<InsertMenuDialog
|
|
234
263
|
onClose={() => setOpen(false)}
|
|
235
264
|
onSelect={insert}
|
|
236
|
-
previewImageUrl={previewImageUrl}
|
|
237
265
|
sections={sections}
|
|
238
266
|
/>
|
|
239
267
|
)}
|
|
@@ -12,6 +12,7 @@ import {
|
|
|
12
12
|
BuildingsIcon,
|
|
13
13
|
CalendarBlankIcon,
|
|
14
14
|
CardsIcon,
|
|
15
|
+
CubeIcon,
|
|
15
16
|
FileTextIcon,
|
|
16
17
|
FolderOpenIcon,
|
|
17
18
|
FootprintsIcon,
|
|
@@ -19,7 +20,6 @@ import {
|
|
|
19
20
|
ListBulletsIcon,
|
|
20
21
|
ListIcon,
|
|
21
22
|
LockKeyIcon,
|
|
22
|
-
PackageIcon,
|
|
23
23
|
QuestionIcon,
|
|
24
24
|
RocketIcon,
|
|
25
25
|
ShapesIcon,
|
|
@@ -45,7 +45,6 @@ const asDuotoneIcon = (IconComponent: Icon): SanityStudioIcon => {
|
|
|
45
45
|
return DuotoneIcon;
|
|
46
46
|
};
|
|
47
47
|
|
|
48
|
-
export const pageBuilderCardIcon = asDuotoneIcon(PackageIcon);
|
|
49
48
|
export const pageBuilderCardListIcon = asDuotoneIcon(ListIcon);
|
|
50
49
|
|
|
51
50
|
export const authorIcon = asDuotoneIcon(UserCircleIcon);
|
|
@@ -54,6 +53,7 @@ export const pageListIcon = asDuotoneIcon(ListBulletsIcon);
|
|
|
54
53
|
|
|
55
54
|
export const blogCategoryIcon = asDuotoneIcon(TagIcon);
|
|
56
55
|
|
|
56
|
+
export const componentIcon = asDuotoneIcon(CubeIcon);
|
|
57
57
|
export const componentsFolderIcon = asDuotoneIcon(ShapesIcon);
|
|
58
58
|
|
|
59
59
|
export const companyDataIcon = asDuotoneIcon(BuildingsIcon);
|
|
@@ -1,5 +1,4 @@
|
|
|
1
1
|
import { contentIcon, pageIcon, type SanityStudioIcon } from "./icons";
|
|
2
|
-
import { singletonComponents } from "./singletons";
|
|
3
2
|
|
|
4
3
|
export type PageBuilderDocumentType =
|
|
5
4
|
| "hero"
|
|
@@ -7,7 +6,7 @@ export type PageBuilderDocumentType =
|
|
|
7
6
|
| "richTextBlock"
|
|
8
7
|
| "gatedContent"
|
|
9
8
|
| "blogContent"
|
|
10
|
-
|
|
|
9
|
+
| "blogCollection";
|
|
11
10
|
|
|
12
11
|
/**
|
|
13
12
|
* A block declares two orthogonal axes. `pageTypes` is which page documents may
|
|
@@ -27,18 +26,13 @@ export const componentCategories = [
|
|
|
27
26
|
|
|
28
27
|
export type ComponentCategory = (typeof componentCategories)[number]["name"];
|
|
29
28
|
|
|
30
|
-
type
|
|
29
|
+
type PageBuilderBlockMember = {
|
|
31
30
|
documentType: PageBuilderDocumentType;
|
|
32
|
-
name: string;
|
|
33
31
|
title: string;
|
|
34
|
-
documentId?: string;
|
|
35
32
|
pageTypes: readonly PageBuilderGroupName[];
|
|
36
33
|
category: ComponentCategory;
|
|
37
34
|
};
|
|
38
35
|
|
|
39
|
-
export const blockPreviewKey = (schemaTypeName: string) =>
|
|
40
|
-
`block.${schemaTypeName}`;
|
|
41
|
-
|
|
42
36
|
export const pageBuilderPageTypes: Array<{
|
|
43
37
|
title: string;
|
|
44
38
|
value: PageBuilderGroupName;
|
|
@@ -56,78 +50,61 @@ export const getPageCategoryIcon = (
|
|
|
56
50
|
pageType: PageBuilderGroupName | undefined | null,
|
|
57
51
|
) => pageCategoryIcons[pageType ?? "generic"];
|
|
58
52
|
|
|
59
|
-
const
|
|
53
|
+
export const pageBuilderBlockMembers: PageBuilderBlockMember[] = [
|
|
60
54
|
{
|
|
61
55
|
documentType: "hero",
|
|
62
|
-
name: "heroReference",
|
|
63
56
|
title: "Heading",
|
|
64
57
|
pageTypes: ["generic"],
|
|
65
58
|
category: "hero",
|
|
66
59
|
},
|
|
67
60
|
{
|
|
68
61
|
documentType: "description",
|
|
69
|
-
name: "descriptionReference",
|
|
70
62
|
title: "Description",
|
|
71
63
|
pageTypes: ["generic"],
|
|
72
64
|
category: "text",
|
|
73
65
|
},
|
|
74
66
|
{
|
|
75
67
|
documentType: "richTextBlock",
|
|
76
|
-
name: "richTextBlockReference",
|
|
77
68
|
title: "Rich Text",
|
|
78
69
|
pageTypes: ["generic"],
|
|
79
70
|
category: "text",
|
|
80
71
|
},
|
|
81
72
|
{
|
|
82
73
|
documentType: "gatedContent",
|
|
83
|
-
name: "gatedContentReference",
|
|
84
74
|
title: "Gated Content",
|
|
85
75
|
pageTypes: ["generic"],
|
|
86
76
|
category: "misc",
|
|
87
77
|
},
|
|
78
|
+
{
|
|
79
|
+
documentType: "blogCollection",
|
|
80
|
+
title: "Blog Collection",
|
|
81
|
+
pageTypes: ["generic"],
|
|
82
|
+
category: "list",
|
|
83
|
+
},
|
|
88
84
|
{
|
|
89
85
|
documentType: "blogContent",
|
|
90
|
-
|
|
91
|
-
title: "Blog Content",
|
|
86
|
+
title: "Blog Posts",
|
|
92
87
|
pageTypes: ["blogEntry"],
|
|
93
88
|
category: "content",
|
|
94
89
|
},
|
|
95
90
|
];
|
|
96
91
|
|
|
97
|
-
const
|
|
98
|
-
singletonComponents.map((component) => ({
|
|
99
|
-
documentType: component.schemaType,
|
|
100
|
-
name: `${component.schemaType}Reference`,
|
|
101
|
-
title: component.title,
|
|
102
|
-
documentId: component.documentId,
|
|
103
|
-
pageTypes: ["generic"],
|
|
104
|
-
category: component.category,
|
|
105
|
-
}));
|
|
106
|
-
|
|
107
|
-
export const pageBuilderReferenceMembers: PageBuilderReferenceMember[] = [
|
|
108
|
-
...reusablePageBuilderReferenceMembers,
|
|
109
|
-
...singletonPageBuilderReferenceMembers,
|
|
110
|
-
];
|
|
111
|
-
|
|
112
|
-
export const getPageBuilderReferenceMember = (name: string) =>
|
|
113
|
-
pageBuilderReferenceMembers.find((member) => member.name === name);
|
|
114
|
-
|
|
115
|
-
export const getPageBuilderReferenceMemberByDocumentType = (
|
|
92
|
+
export const getPageBuilderBlockMember = (
|
|
116
93
|
documentType: PageBuilderDocumentType,
|
|
117
94
|
) =>
|
|
118
|
-
|
|
95
|
+
pageBuilderBlockMembers.find(
|
|
119
96
|
(member) => member.documentType === documentType,
|
|
120
97
|
);
|
|
121
98
|
|
|
122
99
|
const isMemberVisibleForPageType = (
|
|
123
|
-
member:
|
|
100
|
+
member: PageBuilderBlockMember,
|
|
124
101
|
pageType: PageBuilderGroupName | undefined,
|
|
125
102
|
) => member.pageTypes.includes(pageType ?? "generic");
|
|
126
103
|
|
|
127
|
-
export const
|
|
104
|
+
export const getVisiblePageBuilderBlockMembers = (
|
|
128
105
|
pageType: PageBuilderGroupName | undefined,
|
|
129
106
|
) =>
|
|
130
|
-
|
|
107
|
+
pageBuilderBlockMembers.filter((member) =>
|
|
131
108
|
isMemberVisibleForPageType(member, pageType),
|
|
132
109
|
);
|
|
133
110
|
|
|
@@ -135,7 +112,9 @@ export const getVisiblePageBuilderMemberNames = (
|
|
|
135
112
|
pageType: PageBuilderGroupName | undefined,
|
|
136
113
|
) =>
|
|
137
114
|
new Set(
|
|
138
|
-
|
|
115
|
+
getVisiblePageBuilderBlockMembers(pageType).map(
|
|
116
|
+
(member) => member.documentType,
|
|
117
|
+
),
|
|
139
118
|
);
|
|
140
119
|
|
|
141
120
|
export const getVisiblePageBuilderInsertMenuGroups = (
|
|
@@ -155,7 +134,7 @@ export const getInvalidPageBuilderDocumentTypes = (
|
|
|
155
134
|
documentTypes: PageBuilderDocumentType[],
|
|
156
135
|
) =>
|
|
157
136
|
documentTypes.filter((documentType) => {
|
|
158
|
-
const member =
|
|
137
|
+
const member = getPageBuilderBlockMember(documentType);
|
|
159
138
|
|
|
160
139
|
if (!member) return false;
|
|
161
140
|
|
|
@@ -165,18 +144,11 @@ export const getInvalidPageBuilderDocumentTypes = (
|
|
|
165
144
|
export const pageBuilderInsertMenuGroups: Array<{
|
|
166
145
|
name: ComponentCategory;
|
|
167
146
|
title: string;
|
|
168
|
-
of:
|
|
147
|
+
of: PageBuilderDocumentType[];
|
|
169
148
|
}> = componentCategories.map(({ name, title }) => ({
|
|
170
149
|
name,
|
|
171
150
|
title,
|
|
172
|
-
of:
|
|
151
|
+
of: pageBuilderBlockMembers
|
|
173
152
|
.filter((member) => member.category === name)
|
|
174
|
-
.map((member) => member.
|
|
153
|
+
.map((member) => member.documentType),
|
|
175
154
|
}));
|
|
176
|
-
|
|
177
|
-
export const pageBuilderBlockPreviewOptions = pageBuilderReferenceMembers.map(
|
|
178
|
-
(member) => ({
|
|
179
|
-
title: `Block — ${member.title} · ${member.name}`,
|
|
180
|
-
value: blockPreviewKey(member.name),
|
|
181
|
-
}),
|
|
182
|
-
);
|
package/src/modules/features/cms/sanity-pagebuilder/files/lib/integrations/sanity/presentation.ts
CHANGED
|
@@ -43,10 +43,6 @@ const pageResolvedSlugExpression = buildNestedSlugExpression(
|
|
|
43
43
|
"slug.current",
|
|
44
44
|
);
|
|
45
45
|
|
|
46
|
-
const CONTENT_TYPE_PREFIXES: Record<string, string> = {
|
|
47
|
-
blogContent: "blog",
|
|
48
|
-
};
|
|
49
|
-
|
|
50
46
|
const resolveSlugLocation = <T extends { title?: string }>(
|
|
51
47
|
documentStore: DocumentStore,
|
|
52
48
|
id: string,
|
|
@@ -73,10 +69,6 @@ export const presentation = presentationTool({
|
|
|
73
69
|
route: "/",
|
|
74
70
|
filter: `_type == "page" && _id == "${HOMEPAGE_PINNED_PAGE.id}"`,
|
|
75
71
|
},
|
|
76
|
-
...Object.entries(CONTENT_TYPE_PREFIXES).map(([type, prefix]) => ({
|
|
77
|
-
route: `/${prefix}/:slug`,
|
|
78
|
-
filter: `_type == "${type}" && slug.current == $slug`,
|
|
79
|
-
})),
|
|
80
72
|
{
|
|
81
73
|
route: "/:slug+",
|
|
82
74
|
filter: `_type == "page" && ${pageResolvedSlugExpression} == $slug`,
|
|
@@ -97,16 +89,7 @@ export const presentation = presentationTool({
|
|
|
97
89
|
);
|
|
98
90
|
}
|
|
99
91
|
|
|
100
|
-
|
|
101
|
-
if (!prefix) return null;
|
|
102
|
-
|
|
103
|
-
return resolveSlugLocation<{ title?: string; slug?: string }>(
|
|
104
|
-
documentStore,
|
|
105
|
-
params.id,
|
|
106
|
-
`title, "slug": slug.current`,
|
|
107
|
-
(doc) => (doc.slug ? `/${prefix}/${doc.slug}` : null),
|
|
108
|
-
"Untitled",
|
|
109
|
-
);
|
|
92
|
+
return null;
|
|
110
93
|
},
|
|
111
94
|
},
|
|
112
95
|
previewUrl: {
|