Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
27 commits
Select commit Hold shift + click to select a range
512a564
pass through plugins
benlife5 Dec 9, 2025
3687841
puck 0.21 canary
apav-dev Dec 9, 2025
9dc6385
update: bump @measured/puck to version 0.21.0-canary.c78dc826
apav-dev Dec 9, 2025
5d2ee06
Automated update to THIRD-PARTY-NOTICES from github action's 3rd part…
github-actions[bot] Dec 9, 2025
d8f2a08
refactor: enhance type safety in constant value fields and entity fie…
apav-dev Dec 9, 2025
b3f0294
refactor: improve type safety and optional parameters in constant val…
apav-dev Dec 9, 2025
9a8a4dc
docs: auto-generate component documentation
github-actions[bot] Dec 9, 2025
3ba9803
Update component screenshots for visual-editor
github-actions[bot] Dec 9, 2025
2ae1433
Update component screenshots for visual-editor
github-actions[bot] Dec 9, 2025
fd0466f
puck ai
apav-dev Dec 9, 2025
9d22f11
Automated update to THIRD-PARTY-NOTICES from github action's 3rd part…
github-actions[bot] Dec 9, 2025
511fb7d
docs: auto-generate component documentation
github-actions[bot] Dec 9, 2025
f323975
puck ai attempt 2
apav-dev Dec 9, 2025
648c108
feat: integrate AI plugin for enhanced functionality in InternalLayou…
apav-dev Dec 10, 2025
26e9309
refactor: comment out unused template entries in visual editor plugin
apav-dev Dec 10, 2025
fb195af
refactor: comment out unused parameters in useMessageReceivers hook
apav-dev Dec 11, 2025
0aa76ac
refactor: enhance type definitions and improve type safety in YextFie…
apav-dev Dec 11, 2025
ed5282b
feat: implement AI schema validation and enhance YextField component …
apav-dev Dec 11, 2025
8ef49eb
refactor: comment out AI plugin import in YextField component
apav-dev Dec 11, 2025
16fe832
feat: add schema cleaning function for Puck AI compatibility and impl…
apav-dev Dec 11, 2025
0aa0cac
refactor: enhance JSON schema cleaning logic for Puck AI compatibilit…
apav-dev Dec 11, 2025
7853c75
feat: add JSON schema generation for select/radio fields and default …
apav-dev Dec 11, 2025
9f3ff95
refactor: comment out AdvancedSettings and PageSettings components fo…
apav-dev Dec 11, 2025
389e7f6
feat: add AI configuration support in YextEntityFieldSelector and upd…
apav-dev Dec 12, 2025
11ad3ff
refactor: extract AI configuration logic into a separate function and…
apav-dev Dec 12, 2025
43728cf
feat: update AI schemas to use enums for localized values and make co…
apav-dev Dec 12, 2025
ef45acf
Update component screenshots for visual-editor
github-actions[bot] Dec 12, 2025
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion packages/visual-editor/THIRD-PARTY-NOTICES
Original file line number Diff line number Diff line change
Expand Up @@ -1163,7 +1163,8 @@ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.

The following npm packages may be included in this product:

- @measured/puck@0.20.2
- @measured/puck-plugin-heading-analyzer@0.20.2
- @measured/puck@0.21.0-canary.c0db75c1
- next-themes@0.3.0

These packages each contain the following license:
Expand Down
7 changes: 5 additions & 2 deletions packages/visual-editor/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -61,10 +61,13 @@
"i18n:check-empty": "pnpm exec tsx scripts/checkEmptyTranslations.ts"
},
"dependencies": {
"@measured/puck": "0.20.2",
"@measured/puck": "0.21.0-canary.c0db75c1",
"@measured/puck-plugin-heading-analyzer": "^0.20.2",
"@microsoft/api-documenter": "^7.26.29",
"@microsoft/api-extractor": "^7.52.8",
"@microsoft/api-extractor-model": "^7.30.6",
"@puckeditor/cloud-client": "^0.3.1",
"@puckeditor/plugin-ai": "^0.3.1",
"@radix-ui/react-accordion": "^1.2.3",
"@radix-ui/react-alert-dialog": "^1.1.1",
"@radix-ui/react-dialog": "^1.1.13",
Expand Down Expand Up @@ -155,7 +158,7 @@
"vite": "^5.3.5",
"vitepress": "^1.6.3",
"vitest": "^3.2.4",
"zod": "^3.23.8"
"zod": "^4.1.13"
},
"peerDependencies": {
"@yext/pages-components": "1.1.16",
Expand Down
151 changes: 76 additions & 75 deletions packages/visual-editor/src/components/categories/SlotsCategory.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -192,81 +192,82 @@ const ExpandedHeaderComponents = {
},
};

export const SlotsCategoryComponents = {
AddressSlot: { ...Address, permissions: lockedPermissions },
BodyTextSlot: { ...BodyText, permissions: lockedPermissions },
BreadcrumbsSlot: { ...BreadcrumbsSection, permissions: lockedPermissions },
CopyrightMessageSlot: {
...CopyrightMessageSlot,
permissions: lockedPermissions,
},
CTASlot: { ...CTAWrapper, permissions: lockedPermissions },
DirectoryCard: { ...DirectoryCard, permissions: lockedPermissions },
DirectoryGrid: { ...DirectoryGrid, permissions: lockedPermissions },
EmailsSlot: { ...Emails, permissions: lockedPermissions },
EventCard: { ...EventCard, permissions: lockedPermissions },
EventCardsWrapper: { ...EventCardsWrapper, permissions: lockedPermissions },
...ExpandedHeaderComponents,
FAQsWrapperSlot: { ...FAQsWrapperSlot, permissions: lockedPermissions },
FAQSlot: { ...FAQSlot, permissions: lockedPermissions },
FooterExpandedLinkSectionSlot: {
...FooterExpandedLinkSectionSlot,
permissions: lockedPermissions,
},
FooterExpandedLinksWrapper: {
...FooterExpandedLinksWrapper,
permissions: lockedPermissions,
},
FooterLinksSlot: { ...FooterLinksSlot, permissions: lockedPermissions },
FooterLogoSlot: { ...FooterLogoSlot, permissions: lockedPermissions },
FooterSocialLinksSlot: {
...FooterSocialLinksSlot,
permissions: lockedPermissions,
},
FooterUtilityImagesSlot: {
...FooterUtilityImagesSlot,
permissions: lockedPermissions,
},
HeadingTextSlot: { ...HeadingText, permissions: lockedPermissions },
HeroImageSlot: { ...HeroImage, permissions: lockedPermissions },
HoursStatusSlot: { ...HoursStatus, permissions: lockedPermissions },
HoursTableSlot: { ...HoursTable, permissions: lockedPermissions },
ImageSlot: { ...ImageWrapper, permissions: lockedPermissions },
InsightCardsWrapper: {
...InsightCardsWrapper,
permissions: lockedPermissions,
},
InsightCard: { ...InsightCard, permissions: lockedPermissions },
NearbyLocationCardsWrapper: {
...NearbyLocationCardsWrapper,
permissions: lockedPermissions,
},
PhoneNumbersSlot: { ...PhoneList, permissions: lockedPermissions },
PhoneSlot: { ...Phone, permissions: lockedPermissions },
PhotoGalleryWrapper: {
...PhotoGalleryWrapper,
permissions: lockedPermissions,
},
ProductCardsWrapper: {
...ProductCardsWrapper,
permissions: lockedPermissions,
},
ProductCard: { ...ProductCard, permissions: lockedPermissions },
SecondaryFooterSlot: {
...SecondaryFooterSlot,
permissions: lockedPermissions,
},
TeamCard: { ...TeamCard, permissions: lockedPermissions },
TeamCardsWrapper: { ...TeamCardsWrapper, permissions: lockedPermissions },
TestimonialCard: { ...TestimonialCard, permissions: lockedPermissions },
TestimonialCardsWrapper: {
...TestimonialCardsWrapper,
permissions: lockedPermissions,
},
TextListSlot: { ...TextList, permissions: lockedPermissions },
Timestamp: { ...Timestamp, permissions: lockedPermissions },
VideoSlot: { ...Video, permissions: lockedPermissions },
};
export const SlotsCategoryComponents: { [K in keyof SlotsCategoryProps]: any } =
{
AddressSlot: { ...Address, permissions: lockedPermissions },
BodyTextSlot: { ...BodyText, permissions: lockedPermissions },
BreadcrumbsSlot: { ...BreadcrumbsSection, permissions: lockedPermissions },
CopyrightMessageSlot: {
...CopyrightMessageSlot,
permissions: lockedPermissions,
},
CTASlot: { ...CTAWrapper, permissions: lockedPermissions },
DirectoryCard: { ...DirectoryCard, permissions: lockedPermissions },
DirectoryGrid: { ...DirectoryGrid, permissions: lockedPermissions },
EmailsSlot: { ...Emails, permissions: lockedPermissions },
EventCard: { ...EventCard, permissions: lockedPermissions },
EventCardsWrapper: { ...EventCardsWrapper, permissions: lockedPermissions },
...ExpandedHeaderComponents,
FAQsWrapperSlot: { ...FAQsWrapperSlot, permissions: lockedPermissions },
FAQSlot: { ...FAQSlot, permissions: lockedPermissions },
FooterExpandedLinkSectionSlot: {
...FooterExpandedLinkSectionSlot,
permissions: lockedPermissions,
},
FooterExpandedLinksWrapper: {
...FooterExpandedLinksWrapper,
permissions: lockedPermissions,
},
FooterLinksSlot: { ...FooterLinksSlot, permissions: lockedPermissions },
FooterLogoSlot: { ...FooterLogoSlot, permissions: lockedPermissions },
FooterSocialLinksSlot: {
...FooterSocialLinksSlot,
permissions: lockedPermissions,
},
FooterUtilityImagesSlot: {
...FooterUtilityImagesSlot,
permissions: lockedPermissions,
},
HeadingTextSlot: { ...HeadingText, permissions: lockedPermissions },
HeroImageSlot: { ...HeroImage, permissions: lockedPermissions },
HoursStatusSlot: { ...HoursStatus, permissions: lockedPermissions },
HoursTableSlot: { ...HoursTable, permissions: lockedPermissions },
ImageSlot: { ...ImageWrapper, permissions: lockedPermissions },
InsightCardsWrapper: {
...InsightCardsWrapper,
permissions: lockedPermissions,
},
InsightCard: { ...InsightCard, permissions: lockedPermissions },
NearbyLocationCardsWrapper: {
...NearbyLocationCardsWrapper,
permissions: lockedPermissions,
},
PhoneNumbersSlot: { ...PhoneList, permissions: lockedPermissions },
PhoneSlot: { ...Phone, permissions: lockedPermissions },
PhotoGalleryWrapper: {
...PhotoGalleryWrapper,
permissions: lockedPermissions,
},
ProductCardsWrapper: {
...ProductCardsWrapper,
permissions: lockedPermissions,
},
ProductCard: { ...ProductCard, permissions: lockedPermissions },
SecondaryFooterSlot: {
...SecondaryFooterSlot,
permissions: lockedPermissions,
},
TeamCard: { ...TeamCard, permissions: lockedPermissions },
TeamCardsWrapper: { ...TeamCardsWrapper, permissions: lockedPermissions },
TestimonialCard: { ...TestimonialCard, permissions: lockedPermissions },
TestimonialCardsWrapper: {
...TestimonialCardsWrapper,
permissions: lockedPermissions,
},
TextListSlot: { ...TextList, permissions: lockedPermissions },
Timestamp: { ...Timestamp, permissions: lockedPermissions },
VideoSlot: { ...Video, permissions: lockedPermissions },
};

export const SlotsCategory = Object.keys(
SlotsCategoryComponents
Expand Down
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
2 changes: 1 addition & 1 deletion packages/visual-editor/src/editor/Editor.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import "./index.css";
import React, { ErrorInfo, useEffect, useState } from "react";
import { ErrorInfo, useEffect, useState } from "react";
import { ErrorBoundary } from "react-error-boundary";
import { LoadingScreen } from "../internal/puck/components/LoadingScreen.tsx";
import { Toaster } from "../internal/puck/ui/Toaster.tsx";
Expand Down
49 changes: 38 additions & 11 deletions packages/visual-editor/src/editor/YextEntityFieldSelector.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,11 @@
import React from "react";
import { AutoField, FieldLabel, Field, CustomField } from "@measured/puck";
import {
AutoField,
FieldLabel,
Field,
CustomField,
UiState,
} from "@measured/puck";
import {
ConstantValueTypes,
EntityFieldTypes,
Expand Down Expand Up @@ -44,11 +50,10 @@ import { EmbeddedFieldStringInputFromEntity } from "./EmbeddedFieldStringInput.t
import { ComboboxOption } from "../internal/puck/ui/Combobox.tsx";
import { DATE_TIME_CONSTANT_CONFIG } from "../internal/puck/components/DateTimeSelector.tsx";
import { FAQ_SECTION_CONSTANT_CONFIG } from "../internal/puck/constant-value-fields/FAQsSection";
import { getSchemaForYextEntityField, FieldAiConfig } from "./aiSchemas.ts";

const devLogger = new DevLogger();

type RenderProps = Parameters<CustomField<any>["render"]>[0];

/** Represents data that can either be from the Yext Knowledge Graph or statically defined */
export type YextEntityField<T> = {
/** The api name of the Yext field */
Expand Down Expand Up @@ -94,6 +99,8 @@ export type RenderYextEntityFieldSelectorProps<T extends Record<string, any>> =
disableConstantValueToggle?: boolean;
disallowTranslation?: boolean;
typeSelectorConfig?: TypeSelectorConfigProps;
/** AI configuration for Puck AI plugin */
ai?: FieldAiConfig;
};

export const TYPE_TO_CONSTANT_CONFIG: Record<string, Field<any>> = {
Expand Down Expand Up @@ -196,16 +203,36 @@ const returnConstantFieldConfig = (
}
return fieldConfiguration;
};

/**
* Allows the user to select an entity field from the document and set a constant value.
*/
export const YextEntityFieldSelector = <T extends Record<string, any>, U>(
props: RenderYextEntityFieldSelectorProps<T>
): Field<YextEntityField<U>> => {
// Generate default schema based on filter types
const defaultSchema = getSchemaForYextEntityField(props.filter);

// Build AI config with default schema (can be overridden by props.ai)
// If exclude is true, don't include schema (workaround for Puck bug)
const aiConfig: FieldAiConfig = props.ai?.exclude
? { ...props.ai }
: {
...(defaultSchema ? { schema: defaultSchema } : {}),
...props.ai,
};

return {
type: "custom",
render: ({ value, onChange }: RenderProps) => {
// Include AI config if we have a schema or user provided config
...(Object.keys(aiConfig).length > 0 ? { ai: aiConfig } : {}),

render: ({
value,
onChange,
}: {
value: YextEntityField<U>;
onChange: (value: YextEntityField<U>) => void;
}) => {
const toggleConstantValueEnabled = (constantValueEnabled: boolean) => {
onChange({
...value,
Expand All @@ -217,7 +244,7 @@ export const YextEntityFieldSelector = <T extends Record<string, any>, U>(
<>
<ConstantValueModeToggler
fieldTypeFilter={props.filter.types ?? []}
constantValueEnabled={value?.constantValueEnabled}
constantValueEnabled={value?.constantValueEnabled ?? false}
toggleConstantValueEnabled={toggleConstantValueEnabled}
disableConstantValue={props.disableConstantValueToggle}
label={pt(props.label)}
Expand Down Expand Up @@ -366,7 +393,7 @@ export const ConstantValueInput = <T extends Record<string, any>>({
) : (
<AutoField
key={value?.selectedType} // reset when type changes
onChange={(newConstantValue, uiState) =>
onChange={(newConstantValue: T, uiState?: Partial<UiState>) =>
onChange(
{
...value,
Expand All @@ -375,8 +402,8 @@ export const ConstantValueInput = <T extends Record<string, any>>({
uiState
)
}
value={value?.constantValue}
field={constantFieldConfig}
value={value?.constantValue as T}
field={constantFieldConfig as Field<T>}
/>
);

Expand Down Expand Up @@ -499,7 +526,7 @@ export const EntityFieldInput = <T extends Record<string, any>>({
{typeSelectorConfig && (
<AutoField
field={typeSelector!}
onChange={(selectedType, uiState) => {
onChange={(selectedType: string, uiState?: Partial<UiState>) => {
onChange(
{
...value,
Expand All @@ -515,7 +542,7 @@ export const EntityFieldInput = <T extends Record<string, any>>({
<AutoField
key={value?.selectedType}
field={entityFieldSelector}
onChange={(selectedEntityField, uiState) => {
onChange={(selectedEntityField: string, uiState?: Partial<UiState>) => {
onChange(
{
...value,
Expand Down
Loading
Loading