From 14b55dbd2e3aee269df384fa81ebeeaca2bea743 Mon Sep 17 00:00:00 2001 From: rkeerthient Date: Wed, 4 Feb 2026 00:21:43 +0530 Subject: [PATCH 01/90] init test --- .../categories/PageSectionCategory.tsx | 3 + .../pageSections/SearchSection/Search.tsx | 209 ++++++++++++++++++ .../src/components/pageSections/index.ts | 1 + 3 files changed, 213 insertions(+) create mode 100644 packages/visual-editor/src/components/pageSections/SearchSection/Search.tsx diff --git a/packages/visual-editor/src/components/categories/PageSectionCategory.tsx b/packages/visual-editor/src/components/categories/PageSectionCategory.tsx index 7814ca7bf8..a0553b966e 100644 --- a/packages/visual-editor/src/components/categories/PageSectionCategory.tsx +++ b/packages/visual-editor/src/components/categories/PageSectionCategory.tsx @@ -64,6 +64,7 @@ import { ProfessionalHeroSection, ProfessionalHeroSectionProps, } from "../pageSections/ProfessionalHeroSection.tsx"; +import { SearchComponent, SearchProps } from "../pageSections/index.ts"; export interface PageSectionCategoryProps { AboutSection: AboutSectionProps; @@ -84,6 +85,7 @@ export interface PageSectionCategoryProps { TeamSection: TeamSectionProps; TestimonialSection: TestimonialSectionProps; VideoSection: VideoSectionProps; + SearchComponent: SearchProps; } export const PageSectionCategoryComponents = { @@ -105,6 +107,7 @@ export const PageSectionCategoryComponents = { TeamSection, TestimonialSection, VideoSection, + SearchComponent, }; export const PageSectionCategory = Object.keys( diff --git a/packages/visual-editor/src/components/pageSections/SearchSection/Search.tsx b/packages/visual-editor/src/components/pageSections/SearchSection/Search.tsx new file mode 100644 index 0000000000..0857790c8b --- /dev/null +++ b/packages/visual-editor/src/components/pageSections/SearchSection/Search.tsx @@ -0,0 +1,209 @@ +import { ComponentConfig, Fields, WithPuckProps } from "@puckeditor/core"; +import { + CloudRegion, + Environment, + provideHeadless, + SearchConfig, + SearchHeadlessProvider, +} from "@yext/search-headless-react"; +import { SearchBar, SearchI18nextProvider } from "@yext/search-ui-react"; +import React from "react"; +import { BasicSelector } from "../../../editor/BasicSelector.tsx"; +import { DynamicOptionsSelectorType } from "../../../editor/DynamicOptionsSelector.tsx"; +import { YextField } from "../../../editor/YextField.tsx"; +import { useDocument } from "../../../hooks/useDocument.tsx"; +import { msg } from "../../../utils/index.ts"; +import { + DEFAULT_LOCATOR_RESULT_CARD_PROPS, + LocatorResultCardFields, + LocatorResultCardProps, +} from "../../LocatorResultCard.tsx"; +export interface SearchProps { + /** + * The visual theme for the map tiles, chosen from a predefined list of Mapbox styles. + * @defaultValue 'mapbox://styles/mapbox/streets-v12' + */ + mapStyle?: string; + + /** + * Configuration for the filters available in the locator search experience. + */ + filters: { + /** + * If 'true', displays a button to filter for locations that are currently open. + * @defaultValue false + */ + openNowButton: boolean; + /** + * If 'true', displays several distance options to filter searches to only locations within + * a certain radius. + * @defaultValue false + */ + showDistanceOptions: boolean; + /** Which fields are facetable in the search experience */ + facetFields?: DynamicOptionsSelectorType; + }; + + /** + * The starting location for the map. + */ + mapStartingLocation?: { + latitude: string; + longitude: string; + }; + + /** + * Props to customize the locator result card component. + * Controls which fields are displayed and their styling. + */ + resultCard: LocatorResultCardProps; +} +const locatorFields: Fields = { + mapStyle: BasicSelector({ + label: msg("fields.mapStyle", "Map Style"), + options: [ + { + label: msg("fields.options.default", "Default"), + value: "mapbox://styles/mapbox/streets-v12", + }, + { + label: msg("fields.options.satellite", "Satellite"), + value: "mapbox://styles/mapbox/satellite-streets-v12", + }, + { + label: msg("fields.options.light", "Light"), + value: "mapbox://styles/mapbox/light-v11", + }, + { + label: msg("fields.options.dark", "Dark"), + value: "mapbox://styles/mapbox/dark-v11", + }, + { + label: msg("fields.options.navigationDay", "Navigation (Day)"), + value: "mapbox://styles/mapbox/navigation-day-v1", + }, + { + label: msg("fields.options.navigationNight", "Navigation (Night)"), + value: "mapbox://styles/mapbox/navigation-night-v1", + }, + ], + }), + filters: { + label: msg("fields.filters", "Filters"), + type: "object", + objectFields: { + openNowButton: YextField( + msg("fields.options.includeOpenNow", "Include Open Now Button"), + { + type: "radio", + options: [ + { label: msg("fields.options.yes", "Yes"), value: true }, + { label: msg("fields.options.no", "No"), value: false }, + ], + } + ), + showDistanceOptions: YextField( + msg("fields.options.showDistanceOptions", "Include Distance Options"), + { + type: "radio", + options: [ + { label: msg("fields.options.yes", "Yes"), value: true }, + { label: msg("fields.options.no", "No"), value: false }, + ], + } + ), + }, + }, + mapStartingLocation: YextField( + msg("fields.options.mapStartingLocation", "Map Starting Location"), + { + type: "object", + objectFields: { + latitude: YextField(msg("fields.latitude", "Latitude"), { + type: "text", + }), + longitude: YextField(msg("fields.longitude", "Longitude"), { + type: "text", + }), + }, + } + ), + resultCard: LocatorResultCardFields, +}; +const EXPERIENCE_VERSION = "PRODUCTION"; + +export const searchConfig: SearchConfig = { + apiKey: import.meta.env.YEXT_PUBLIC_SEARCH_API_KEY, + experienceKey: import.meta.env.YEXT_PUBLIC_SEARCH_EXP_KEY, + locale: "en", + experienceVersion: EXPERIENCE_VERSION, + cloudRegion: CloudRegion.US, + environment: Environment.PROD, +}; +const SearchWrapper = (props: WithPuckProps) => { + const streamDocument = useDocument(); + const { searchAnalyticsConfig, searcher } = React.useMemo(() => { + const searchHeadlessConfig = provideHeadless(searchConfig); + if (searchHeadlessConfig === undefined) { + return { searchAnalyticsConfig: undefined, searcher: undefined }; + } + + const searchAnalyticsConfig = provideHeadless(searchConfig); + return { + searchAnalyticsConfig, + searcher: provideHeadless(searchConfig), + }; + }, [streamDocument.id, streamDocument.locale]); + + if (searcher === undefined || searchAnalyticsConfig === undefined) { + console.warn( + "Could not create Locator component because Search Headless or Search Analytics config is undefined. Please check your environment variables." + ); + return <>; + } + searcher.setSessionTrackingEnabled(true); + return ( + + + {/* */} + + {/* */} + + + ); +}; + +const SearchInternal = (props: WithPuckProps) => { + console.log(props); + + return ( + <> + + + ); +}; +/** + * Available on Search templates. + */ +export const SearchComponent: ComponentConfig<{ props: SearchProps }> = { + fields: locatorFields, + defaultProps: { + filters: { + openNowButton: false, + showDistanceOptions: false, + }, + resultCard: DEFAULT_LOCATOR_RESULT_CARD_PROPS, + }, + label: msg("components.search", "Search"), + render: (props) => , +}; diff --git a/packages/visual-editor/src/components/pageSections/index.ts b/packages/visual-editor/src/components/pageSections/index.ts index a399c08613..2074e2df7b 100644 --- a/packages/visual-editor/src/components/pageSections/index.ts +++ b/packages/visual-editor/src/components/pageSections/index.ts @@ -86,3 +86,4 @@ export { type ProfessionalHeroSectionProps, type ProfessionalHeroStyles, } from "./ProfessionalHeroSection.tsx"; +export { SearchComponent, type SearchProps } from "./SearchSection/Search.tsx"; From 84e458ca093e67c882b64d6184a13695d6fc1e04 Mon Sep 17 00:00:00 2001 From: rkeerthient Date: Fri, 6 Feb 2026 00:14:38 +0530 Subject: [PATCH 02/90] working copy --- .../pageSections/SearchSection/Search.tsx | 209 -------------- .../SearchSectionClassic/Layout.tsx | 27 ++ .../SearchSectionClassic/Search.tsx | 261 ++++++++++++++++++ .../src/components/pageSections/index.ts | 5 +- 4 files changed, 292 insertions(+), 210 deletions(-) delete mode 100644 packages/visual-editor/src/components/pageSections/SearchSection/Search.tsx create mode 100644 packages/visual-editor/src/components/pageSections/SearchSectionClassic/Layout.tsx create mode 100644 packages/visual-editor/src/components/pageSections/SearchSectionClassic/Search.tsx diff --git a/packages/visual-editor/src/components/pageSections/SearchSection/Search.tsx b/packages/visual-editor/src/components/pageSections/SearchSection/Search.tsx deleted file mode 100644 index 0857790c8b..0000000000 --- a/packages/visual-editor/src/components/pageSections/SearchSection/Search.tsx +++ /dev/null @@ -1,209 +0,0 @@ -import { ComponentConfig, Fields, WithPuckProps } from "@puckeditor/core"; -import { - CloudRegion, - Environment, - provideHeadless, - SearchConfig, - SearchHeadlessProvider, -} from "@yext/search-headless-react"; -import { SearchBar, SearchI18nextProvider } from "@yext/search-ui-react"; -import React from "react"; -import { BasicSelector } from "../../../editor/BasicSelector.tsx"; -import { DynamicOptionsSelectorType } from "../../../editor/DynamicOptionsSelector.tsx"; -import { YextField } from "../../../editor/YextField.tsx"; -import { useDocument } from "../../../hooks/useDocument.tsx"; -import { msg } from "../../../utils/index.ts"; -import { - DEFAULT_LOCATOR_RESULT_CARD_PROPS, - LocatorResultCardFields, - LocatorResultCardProps, -} from "../../LocatorResultCard.tsx"; -export interface SearchProps { - /** - * The visual theme for the map tiles, chosen from a predefined list of Mapbox styles. - * @defaultValue 'mapbox://styles/mapbox/streets-v12' - */ - mapStyle?: string; - - /** - * Configuration for the filters available in the locator search experience. - */ - filters: { - /** - * If 'true', displays a button to filter for locations that are currently open. - * @defaultValue false - */ - openNowButton: boolean; - /** - * If 'true', displays several distance options to filter searches to only locations within - * a certain radius. - * @defaultValue false - */ - showDistanceOptions: boolean; - /** Which fields are facetable in the search experience */ - facetFields?: DynamicOptionsSelectorType; - }; - - /** - * The starting location for the map. - */ - mapStartingLocation?: { - latitude: string; - longitude: string; - }; - - /** - * Props to customize the locator result card component. - * Controls which fields are displayed and their styling. - */ - resultCard: LocatorResultCardProps; -} -const locatorFields: Fields = { - mapStyle: BasicSelector({ - label: msg("fields.mapStyle", "Map Style"), - options: [ - { - label: msg("fields.options.default", "Default"), - value: "mapbox://styles/mapbox/streets-v12", - }, - { - label: msg("fields.options.satellite", "Satellite"), - value: "mapbox://styles/mapbox/satellite-streets-v12", - }, - { - label: msg("fields.options.light", "Light"), - value: "mapbox://styles/mapbox/light-v11", - }, - { - label: msg("fields.options.dark", "Dark"), - value: "mapbox://styles/mapbox/dark-v11", - }, - { - label: msg("fields.options.navigationDay", "Navigation (Day)"), - value: "mapbox://styles/mapbox/navigation-day-v1", - }, - { - label: msg("fields.options.navigationNight", "Navigation (Night)"), - value: "mapbox://styles/mapbox/navigation-night-v1", - }, - ], - }), - filters: { - label: msg("fields.filters", "Filters"), - type: "object", - objectFields: { - openNowButton: YextField( - msg("fields.options.includeOpenNow", "Include Open Now Button"), - { - type: "radio", - options: [ - { label: msg("fields.options.yes", "Yes"), value: true }, - { label: msg("fields.options.no", "No"), value: false }, - ], - } - ), - showDistanceOptions: YextField( - msg("fields.options.showDistanceOptions", "Include Distance Options"), - { - type: "radio", - options: [ - { label: msg("fields.options.yes", "Yes"), value: true }, - { label: msg("fields.options.no", "No"), value: false }, - ], - } - ), - }, - }, - mapStartingLocation: YextField( - msg("fields.options.mapStartingLocation", "Map Starting Location"), - { - type: "object", - objectFields: { - latitude: YextField(msg("fields.latitude", "Latitude"), { - type: "text", - }), - longitude: YextField(msg("fields.longitude", "Longitude"), { - type: "text", - }), - }, - } - ), - resultCard: LocatorResultCardFields, -}; -const EXPERIENCE_VERSION = "PRODUCTION"; - -export const searchConfig: SearchConfig = { - apiKey: import.meta.env.YEXT_PUBLIC_SEARCH_API_KEY, - experienceKey: import.meta.env.YEXT_PUBLIC_SEARCH_EXP_KEY, - locale: "en", - experienceVersion: EXPERIENCE_VERSION, - cloudRegion: CloudRegion.US, - environment: Environment.PROD, -}; -const SearchWrapper = (props: WithPuckProps) => { - const streamDocument = useDocument(); - const { searchAnalyticsConfig, searcher } = React.useMemo(() => { - const searchHeadlessConfig = provideHeadless(searchConfig); - if (searchHeadlessConfig === undefined) { - return { searchAnalyticsConfig: undefined, searcher: undefined }; - } - - const searchAnalyticsConfig = provideHeadless(searchConfig); - return { - searchAnalyticsConfig, - searcher: provideHeadless(searchConfig), - }; - }, [streamDocument.id, streamDocument.locale]); - - if (searcher === undefined || searchAnalyticsConfig === undefined) { - console.warn( - "Could not create Locator component because Search Headless or Search Analytics config is undefined. Please check your environment variables." - ); - return <>; - } - searcher.setSessionTrackingEnabled(true); - return ( - - - {/* */} - - {/* */} - - - ); -}; - -const SearchInternal = (props: WithPuckProps) => { - console.log(props); - - return ( - <> - - - ); -}; -/** - * Available on Search templates. - */ -export const SearchComponent: ComponentConfig<{ props: SearchProps }> = { - fields: locatorFields, - defaultProps: { - filters: { - openNowButton: false, - showDistanceOptions: false, - }, - resultCard: DEFAULT_LOCATOR_RESULT_CARD_PROPS, - }, - label: msg("components.search", "Search"), - render: (props) => , -}; diff --git a/packages/visual-editor/src/components/pageSections/SearchSectionClassic/Layout.tsx b/packages/visual-editor/src/components/pageSections/SearchSectionClassic/Layout.tsx new file mode 100644 index 0000000000..8c9a85eb5a --- /dev/null +++ b/packages/visual-editor/src/components/pageSections/SearchSectionClassic/Layout.tsx @@ -0,0 +1,27 @@ +import { SectionProps, DefaultRawDataType } from "@yext/search-ui-react"; + +// Define Props +interface LayoutProps { + layoutType?: "Grid" | "Flex"; + data: SectionProps; +} + +export const SearchLayout = ({ + layoutType = "Grid", + data: { results, header, CardComponent }, +}: LayoutProps) => { + console.log(header); + + if (!CardComponent) { + return
Missing Card Component
; + } + const classNames = + layoutType === "Grid" ? "grid grid-cols-3 gap-4 w-full" : "flex w-full"; + return ( +
+ {results.map((r: any, index: number) => ( + + ))} +
+ ); +}; diff --git a/packages/visual-editor/src/components/pageSections/SearchSectionClassic/Search.tsx b/packages/visual-editor/src/components/pageSections/SearchSectionClassic/Search.tsx new file mode 100644 index 0000000000..f97fdcfe47 --- /dev/null +++ b/packages/visual-editor/src/components/pageSections/SearchSectionClassic/Search.tsx @@ -0,0 +1,261 @@ +import { ComponentConfig, Fields, WithPuckProps } from "@puckeditor/core"; +import { + CloudRegion, + Environment, + provideHeadless, + SearchConfig, + SearchHeadlessProvider, +} from "@yext/search-headless-react"; +import { + DefaultRawDataType, + SearchBar, + SearchI18nextProvider, + SectionProps, + StandardCard, + UniversalResults, +} from "@yext/search-ui-react"; +import React from "react"; +import { YextField } from "../../../editor/YextField.tsx"; +import { useDocument } from "../../../hooks/useDocument.tsx"; +import { msg } from "../../../utils/index.ts"; +import { + DEFAULT_LOCATOR_RESULT_CARD_PROPS, + LocatorResultCardFields, + LocatorResultCardProps, +} from "../../LocatorResultCard.tsx"; +import { PageSection } from "../../atoms/pageSection.tsx"; + +export type VerticalLayout = "Grid" | "Flex" | "Map"; + +export interface VerticalConfig { + label: string; + verticalKey: string; + layout: VerticalLayout; + universalLimit: number; + verticalLimit: number; +} + +export interface SearchProps { + verticals: VerticalConfig[]; + resultCard: LocatorResultCardProps; +} + +const locatorFields: Fields = { + verticals: { + label: msg("fields.verticals", "Verticals"), + type: "array", + arrayFields: { + label: YextField(msg("fields.label", "Label"), { type: "text" }), + + verticalKey: YextField(msg("fields.verticalKey", "Vertical Key"), { + type: "text", + }), + + layout: YextField(msg("fields.layout", "Layout"), { + type: "radio", + options: [ + { label: "Grid", value: "Grid" }, + { label: "Flex", value: "Flex" }, + { label: "Map", value: "Map" }, + ], + }), + + universalLimit: YextField( + msg("fields.universalLimit", "Universal Limit"), + { type: "number" } + ), + + verticalLimit: YextField(msg("fields.verticalLimit", "Vertical Limit"), { + type: "number", + }), + }, + getItemSummary: (item) => item?.label || "Vertical", + }, + resultCard: LocatorResultCardFields, +}; +const EXPERIENCE_VERSION = "PRODUCTION"; + +export const searchConfig: SearchConfig = { + apiKey: "fb73f1bf6a262bc3255bcb938088204f", + experienceKey: "ukg-fins", + locale: "en", + experienceVersion: EXPERIENCE_VERSION, + cloudRegion: CloudRegion.US, + environment: Environment.PROD, +}; +const SearchWrapper = (props: WithPuckProps) => { + const streamDocument = useDocument(); + const { searchAnalyticsConfig, searcher } = React.useMemo(() => { + const searchHeadlessConfig = provideHeadless(searchConfig); + if (searchHeadlessConfig === undefined) { + return { searchAnalyticsConfig: undefined, searcher: undefined }; + } + + const searchAnalyticsConfig = provideHeadless(searchConfig); + return { + searchAnalyticsConfig, + searcher: provideHeadless(searchConfig), + }; + }, [streamDocument.id, streamDocument.locale]); + + if (searcher === undefined || searchAnalyticsConfig === undefined) { + console.warn( + "Could not create Locator component because Search Headless or Search Analytics config is undefined. Please check your environment variables." + ); + return <>; + } + searcher.setSessionTrackingEnabled(true); + return ( + + + {/* */} + + {/* */} + + + ); +}; + +export const verticalConfigMap = { + faq: { + label: "FAQs", + viewAllButton: true, + CardComponent: StandardCard, + universalLimit: 3, + verticalLimit: 5, + }, + "financial-professional": { + label: "Professionals", + viewAllButton: true, + CardComponent: StandardCard, + universalLimit: 3, + verticalLimit: 5, + }, + + locations: { + label: "Locations", + viewAllButton: true, + CardComponent: StandardCard, + universalLimit: 3, + verticalLimit: 5, + }, + + jobs: { + label: "Jobs", + viewAllButton: true, + CardComponent: StandardCard, + universalLimit: 3, + verticalLimit: 5, + }, + + events: { + label: "Events", + viewAllButton: true, + CardComponent: StandardCard, + universalLimit: 3, + verticalLimit: 5, + }, + + product: { + label: "Products", + viewAllButton: true, + CardComponent: StandardCard, + universalLimit: 3, + verticalLimit: 5, + }, +}; +const SearchInternal = ({ verticals }: WithPuckProps) => { + const verticalConfigMap = React.useMemo( + () => buildVerticalConfigMap(verticals), + [verticals] + ); + + return ( + + + + + ); +}; +const buildVerticalConfigMap = (verticals: VerticalConfig[]) => { + const map: Record = {}; + + verticals.forEach((v) => { + const Section = (props: SectionProps) => ( + + ); + + map[v.verticalKey] = { + label: v.label, + viewAllButton: true, + SectionComponent: Section, + CardComponent: StandardCard, + universalLimit: v.universalLimit, + verticalLimit: v.verticalLimit, + }; + }); + + return map; +}; + +const SearchLayout = ({ + layout, + data: { results, CardComponent }, +}: { + layout: VerticalLayout; + data: SectionProps; +}) => { + if (!CardComponent) return null; + + const className = + layout === "Grid" + ? "grid grid-cols-3 gap-4 w-full" + : layout === "Flex" + ? "flex flex-col gap-4 w-full" + : "flex flex-col w-full"; + + return ( +
+ {results.map((r, i) => ( + + ))} +
+ ); +}; + +export const SearchComponent: ComponentConfig<{ props: SearchProps }> = { + label: msg("components.search", "Search"), + fields: locatorFields, + + defaultProps: { + verticals: [ + { + label: "FAQs", + verticalKey: "faq", + layout: "Flex", + universalLimit: 3, + verticalLimit: 5, + }, + { + label: "Products", + verticalKey: "product", + layout: "Grid", + universalLimit: 3, + verticalLimit: 5, + }, + { + label: "Locations", + verticalKey: "locations", + layout: "Map", + universalLimit: 3, + verticalLimit: 5, + }, + ], + resultCard: DEFAULT_LOCATOR_RESULT_CARD_PROPS, + }, + + render: (props) => , +}; diff --git a/packages/visual-editor/src/components/pageSections/index.ts b/packages/visual-editor/src/components/pageSections/index.ts index 2074e2df7b..f7d995a3d4 100644 --- a/packages/visual-editor/src/components/pageSections/index.ts +++ b/packages/visual-editor/src/components/pageSections/index.ts @@ -86,4 +86,7 @@ export { type ProfessionalHeroSectionProps, type ProfessionalHeroStyles, } from "./ProfessionalHeroSection.tsx"; -export { SearchComponent, type SearchProps } from "./SearchSection/Search.tsx"; +export { + SearchComponent, + type SearchProps, +} from "./SearchSectionClassic/Search.tsx"; From 2d73be3d081b2dcc6f1a0e2bc72d0fdc9ed2e598 Mon Sep 17 00:00:00 2001 From: rkeerthient Date: Fri, 6 Feb 2026 13:29:55 +0530 Subject: [PATCH 03/90] code cleanup --- .../pageSections/SearchSectionClassic/Search.tsx | 8 -------- 1 file changed, 8 deletions(-) diff --git a/packages/visual-editor/src/components/pageSections/SearchSectionClassic/Search.tsx b/packages/visual-editor/src/components/pageSections/SearchSectionClassic/Search.tsx index f97fdcfe47..bde12c7390 100644 --- a/packages/visual-editor/src/components/pageSections/SearchSectionClassic/Search.tsx +++ b/packages/visual-editor/src/components/pageSections/SearchSectionClassic/Search.tsx @@ -18,11 +18,6 @@ import React from "react"; import { YextField } from "../../../editor/YextField.tsx"; import { useDocument } from "../../../hooks/useDocument.tsx"; import { msg } from "../../../utils/index.ts"; -import { - DEFAULT_LOCATOR_RESULT_CARD_PROPS, - LocatorResultCardFields, - LocatorResultCardProps, -} from "../../LocatorResultCard.tsx"; import { PageSection } from "../../atoms/pageSection.tsx"; export type VerticalLayout = "Grid" | "Flex" | "Map"; @@ -37,7 +32,6 @@ export interface VerticalConfig { export interface SearchProps { verticals: VerticalConfig[]; - resultCard: LocatorResultCardProps; } const locatorFields: Fields = { @@ -71,7 +65,6 @@ const locatorFields: Fields = { }, getItemSummary: (item) => item?.label || "Vertical", }, - resultCard: LocatorResultCardFields, }; const EXPERIENCE_VERSION = "PRODUCTION"; @@ -254,7 +247,6 @@ export const SearchComponent: ComponentConfig<{ props: SearchProps }> = { verticalLimit: 5, }, ], - resultCard: DEFAULT_LOCATOR_RESULT_CARD_PROPS, }, render: (props) => , From b5c0bb0d41c30cf9033edef05393e985ae7ae167 Mon Sep 17 00:00:00 2001 From: rkeerthient Date: Fri, 6 Feb 2026 13:39:41 +0530 Subject: [PATCH 04/90] nit updates --- .../categories/PageSectionCategory.tsx | 9 ++++++--- .../{Search.tsx => ClassicSearch.tsx} | 20 ++++++++++--------- .../src/components/pageSections/index.ts | 6 +++--- 3 files changed, 20 insertions(+), 15 deletions(-) rename packages/visual-editor/src/components/pageSections/SearchSectionClassic/{Search.tsx => ClassicSearch.tsx} (91%) diff --git a/packages/visual-editor/src/components/categories/PageSectionCategory.tsx b/packages/visual-editor/src/components/categories/PageSectionCategory.tsx index a0553b966e..b349cf0af5 100644 --- a/packages/visual-editor/src/components/categories/PageSectionCategory.tsx +++ b/packages/visual-editor/src/components/categories/PageSectionCategory.tsx @@ -64,7 +64,10 @@ import { ProfessionalHeroSection, ProfessionalHeroSectionProps, } from "../pageSections/ProfessionalHeroSection.tsx"; -import { SearchComponent, SearchProps } from "../pageSections/index.ts"; +import { + ClassicSearchComponent, + ClassicSearchProps, +} from "../pageSections/index.ts"; export interface PageSectionCategoryProps { AboutSection: AboutSectionProps; @@ -85,7 +88,7 @@ export interface PageSectionCategoryProps { TeamSection: TeamSectionProps; TestimonialSection: TestimonialSectionProps; VideoSection: VideoSectionProps; - SearchComponent: SearchProps; + ClassicSearchComponent: ClassicSearchProps; } export const PageSectionCategoryComponents = { @@ -107,7 +110,7 @@ export const PageSectionCategoryComponents = { TeamSection, TestimonialSection, VideoSection, - SearchComponent, + ClassicSearchComponent, }; export const PageSectionCategory = Object.keys( diff --git a/packages/visual-editor/src/components/pageSections/SearchSectionClassic/Search.tsx b/packages/visual-editor/src/components/pageSections/SearchSectionClassic/ClassicSearch.tsx similarity index 91% rename from packages/visual-editor/src/components/pageSections/SearchSectionClassic/Search.tsx rename to packages/visual-editor/src/components/pageSections/SearchSectionClassic/ClassicSearch.tsx index bde12c7390..870c4b069e 100644 --- a/packages/visual-editor/src/components/pageSections/SearchSectionClassic/Search.tsx +++ b/packages/visual-editor/src/components/pageSections/SearchSectionClassic/ClassicSearch.tsx @@ -20,9 +20,9 @@ import { useDocument } from "../../../hooks/useDocument.tsx"; import { msg } from "../../../utils/index.ts"; import { PageSection } from "../../atoms/pageSection.tsx"; -export type VerticalLayout = "Grid" | "Flex" | "Map"; +type VerticalLayout = "Grid" | "Flex" | "Map"; -export interface VerticalConfig { +interface VerticalConfig { label: string; verticalKey: string; layout: VerticalLayout; @@ -30,11 +30,11 @@ export interface VerticalConfig { verticalLimit: number; } -export interface SearchProps { +export interface ClassicSearchProps { verticals: VerticalConfig[]; } -const locatorFields: Fields = { +const locatorFields: Fields = { verticals: { label: msg("fields.verticals", "Verticals"), type: "array", @@ -76,7 +76,7 @@ export const searchConfig: SearchConfig = { cloudRegion: CloudRegion.US, environment: Environment.PROD, }; -const SearchWrapper = (props: WithPuckProps) => { +const ClassicSearchWrapper = (props: WithPuckProps) => { const streamDocument = useDocument(); const { searchAnalyticsConfig, searcher } = React.useMemo(() => { const searchHeadlessConfig = provideHeadless(searchConfig); @@ -160,7 +160,7 @@ export const verticalConfigMap = { verticalLimit: 5, }, }; -const SearchInternal = ({ verticals }: WithPuckProps) => { +const SearchInternal = ({ verticals }: WithPuckProps) => { const verticalConfigMap = React.useMemo( () => buildVerticalConfigMap(verticals), [verticals] @@ -219,8 +219,10 @@ const SearchLayout = ({ ); }; -export const SearchComponent: ComponentConfig<{ props: SearchProps }> = { - label: msg("components.search", "Search"), +export const ClassicSearchComponent: ComponentConfig<{ + props: ClassicSearchProps; +}> = { + label: msg("components.classicSearch", "Classic Search"), fields: locatorFields, defaultProps: { @@ -249,5 +251,5 @@ export const SearchComponent: ComponentConfig<{ props: SearchProps }> = { ], }, - render: (props) => , + render: (props) => , }; diff --git a/packages/visual-editor/src/components/pageSections/index.ts b/packages/visual-editor/src/components/pageSections/index.ts index f7d995a3d4..2c559d1b2d 100644 --- a/packages/visual-editor/src/components/pageSections/index.ts +++ b/packages/visual-editor/src/components/pageSections/index.ts @@ -87,6 +87,6 @@ export { type ProfessionalHeroStyles, } from "./ProfessionalHeroSection.tsx"; export { - SearchComponent, - type SearchProps, -} from "./SearchSectionClassic/Search.tsx"; + ClassicSearchComponent, + type ClassicSearchProps, +} from "./SearchSectionClassic/ClassicSearch.tsx"; From e516d7087b59d2b23ccaf1a524bb82726ad9e78f Mon Sep 17 00:00:00 2001 From: rkeerthient Date: Fri, 6 Feb 2026 13:41:43 +0530 Subject: [PATCH 05/90] cleared keys --- .../pageSections/SearchSectionClassic/ClassicSearch.tsx | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/visual-editor/src/components/pageSections/SearchSectionClassic/ClassicSearch.tsx b/packages/visual-editor/src/components/pageSections/SearchSectionClassic/ClassicSearch.tsx index 870c4b069e..1c9a0458ba 100644 --- a/packages/visual-editor/src/components/pageSections/SearchSectionClassic/ClassicSearch.tsx +++ b/packages/visual-editor/src/components/pageSections/SearchSectionClassic/ClassicSearch.tsx @@ -69,8 +69,8 @@ const locatorFields: Fields = { const EXPERIENCE_VERSION = "PRODUCTION"; export const searchConfig: SearchConfig = { - apiKey: "fb73f1bf6a262bc3255bcb938088204f", - experienceKey: "ukg-fins", + apiKey: "", + experienceKey: "", locale: "en", experienceVersion: EXPERIENCE_VERSION, cloudRegion: CloudRegion.US, From e657d79ee9007013b8c67972a7f623a780b589e9 Mon Sep 17 00:00:00 2001 From: rkeerthient Date: Fri, 6 Feb 2026 14:50:32 +0530 Subject: [PATCH 06/90] Init Search working template --- .../categories/PageSectionCategory.tsx | 6 + .../components/categories/SlotsCategory.tsx | 184 +++++------ .../pageSections/SearchSection/Search.tsx | 287 ++++++++++++++++++ .../SearchSection/SearchBarSlot.tsx | 50 +++ .../src/components/pageSections/index.ts | 4 + 5 files changed, 442 insertions(+), 89 deletions(-) create mode 100644 packages/visual-editor/src/components/pageSections/SearchSection/Search.tsx create mode 100644 packages/visual-editor/src/components/pageSections/SearchSection/SearchBarSlot.tsx diff --git a/packages/visual-editor/src/components/categories/PageSectionCategory.tsx b/packages/visual-editor/src/components/categories/PageSectionCategory.tsx index b349cf0af5..7787ed72ab 100644 --- a/packages/visual-editor/src/components/categories/PageSectionCategory.tsx +++ b/packages/visual-editor/src/components/categories/PageSectionCategory.tsx @@ -68,6 +68,10 @@ import { ClassicSearchComponent, ClassicSearchProps, } from "../pageSections/index.ts"; +import { + SearchComponentProps, + SearchComponent, +} from "../pageSections/SearchSection/Search.tsx"; export interface PageSectionCategoryProps { AboutSection: AboutSectionProps; @@ -89,6 +93,7 @@ export interface PageSectionCategoryProps { TestimonialSection: TestimonialSectionProps; VideoSection: VideoSectionProps; ClassicSearchComponent: ClassicSearchProps; + SearchComponent: SearchComponentProps; } export const PageSectionCategoryComponents = { @@ -111,6 +116,7 @@ export const PageSectionCategoryComponents = { TestimonialSection, VideoSection, ClassicSearchComponent, + SearchComponent, }; export const PageSectionCategory = Object.keys( diff --git a/packages/visual-editor/src/components/categories/SlotsCategory.tsx b/packages/visual-editor/src/components/categories/SlotsCategory.tsx index 20978f37fc..5b7adfaa36 100644 --- a/packages/visual-editor/src/components/categories/SlotsCategory.tsx +++ b/packages/visual-editor/src/components/categories/SlotsCategory.tsx @@ -1,81 +1,53 @@ import { Address, AddressProps } from "../contentBlocks/Address.tsx"; +import { BodyText, BodyTextProps } from "../contentBlocks/BodyText.tsx"; +import { CTAWrapper, CTAWrapperProps } from "../contentBlocks/CtaWrapper.tsx"; +import { Emails, EmailsProps } from "../contentBlocks/Emails.tsx"; import { - AboutSectionDetailsColumn, - AboutSectionDetailsColumnProps, -} from "../pageSections/AboutSection/AboutSectionDetailsColumn.tsx"; -import { BodyTextProps, BodyText } from "../contentBlocks/BodyText.tsx"; -import { CTAWrapperProps, CTAWrapper } from "../contentBlocks/CtaWrapper.tsx"; -import { - HeadingTextProps, HeadingText, + HeadingTextProps, } from "../contentBlocks/HeadingText.tsx"; -import { HoursTable, HoursTableProps } from "../contentBlocks/HoursTable.tsx"; -import { - ImageWrapperProps, - ImageWrapper, -} from "../contentBlocks/image/Image.tsx"; -import { Video, VideoProps } from "../contentBlocks/Video.tsx"; -import { TextList, TextListProps } from "../contentBlocks/TextList.tsx"; -import { PhoneListProps, PhoneList } from "../contentBlocks/PhoneList.tsx"; -import { - ProductCardsWrapper, - ProductCardsWrapperProps, -} from "../pageSections/ProductSection/ProductCardsWrapper.tsx"; -import { - ProductCard, - ProductCardProps, -} from "../pageSections/ProductSection/ProductCard.tsx"; -import { - EventCardsWrapper, - EventCardsWrapperProps, -} from "../pageSections/EventSection/EventCardsWrapper.tsx"; -import { - EventCard, - EventCardProps, -} from "../pageSections/EventSection/EventCard.tsx"; -import { Emails, EmailsProps } from "../contentBlocks/Emails.tsx"; import { HoursStatus, HoursStatusProps, } from "../contentBlocks/HoursStatus.tsx"; +import { HoursTable, HoursTableProps } from "../contentBlocks/HoursTable.tsx"; import { HeroImage, HeroImageProps, } from "../contentBlocks/image/HeroImage.tsx"; -import { Timestamp, TimestampProps } from "../contentBlocks/Timestamp.tsx"; import { - NearbyLocationCardsWrapper, - NearbyLocationCardsWrapperProps, -} from "../pageSections/NearbyLocations/NearbyLocationsCardsWrapper.tsx"; -import { - InsightCardsWrapper, - InsightCardsWrapperProps, -} from "../pageSections/InsightSection/InsightCardsWrapper.tsx"; + ImageWrapper, + ImageWrapperProps, +} from "../contentBlocks/image/Image.tsx"; +import { Phone, PhoneProps } from "../contentBlocks/Phone.tsx"; +import { PhoneList, PhoneListProps } from "../contentBlocks/PhoneList.tsx"; +import { TextList, TextListProps } from "../contentBlocks/TextList.tsx"; +import { Timestamp, TimestampProps } from "../contentBlocks/Timestamp.tsx"; +import { Video, VideoProps } from "../contentBlocks/Video.tsx"; import { - InsightCard, - InsightCardProps, -} from "../pageSections/InsightSection/InsightCard.tsx"; + DirectoryCard, + DirectoryCardProps, +} from "../directory/DirectoryCard.tsx"; import { - PhotoGalleryWrapperProps, - PhotoGalleryWrapper, -} from "../pageSections/PhotoGallerySection/PhotoGalleryWrapper.tsx"; -import { FAQCard, FAQCardProps } from "../pageSections/FAQsSection/FAQCard.tsx"; + DirectoryGrid, + DirectoryGridProps, +} from "../directory/DirectoryWrapper.tsx"; import { - TeamCardsWrapper, - TeamCardsWrapperProps, -} from "../pageSections/TeamSection/TeamCardsWrapper.tsx"; + CopyrightMessageSlot, + CopyrightMessageSlotProps, +} from "../footer/CopyrightMessageSlot.tsx"; import { - TeamCard, - TeamCardProps, -} from "../pageSections/TeamSection/TeamCard.tsx"; + FooterExpandedLinkSectionSlot, + FooterExpandedLinkSectionSlotProps, +} from "../footer/FooterExpandedLinkSectionSlot.tsx"; import { - TestimonialCardsWrapper, - TestimonialCardsWrapperProps, -} from "../pageSections/TestimonialSection/TestimonialCardsWrapper.tsx"; + FooterExpandedLinksWrapper, + FooterExpandedLinksWrapperProps, +} from "../footer/FooterExpandedLinksWrapper.tsx"; import { - TestimonialCard, - TestimonialCardProps, -} from "../pageSections/TestimonialSection/TestimonialCard.tsx"; + FooterLinksSlot, + FooterLinksSlotProps, +} from "../footer/FooterLinksSlot.tsx"; import { FooterLogoSlot, FooterLogoSlotProps, @@ -88,39 +60,11 @@ import { FooterUtilityImagesSlot, FooterUtilityImagesSlotProps, } from "../footer/FooterUtilityImagesSlot.tsx"; -import { - FooterLinksSlot, - FooterLinksSlotProps, -} from "../footer/FooterLinksSlot.tsx"; -import { - FooterExpandedLinkSectionSlot, - FooterExpandedLinkSectionSlotProps, -} from "../footer/FooterExpandedLinkSectionSlot.tsx"; -import { - FooterExpandedLinksWrapper, - FooterExpandedLinksWrapperProps, -} from "../footer/FooterExpandedLinksWrapper.tsx"; -import { - CopyrightMessageSlot, - CopyrightMessageSlotProps, -} from "../footer/CopyrightMessageSlot.tsx"; import { SecondaryFooterSlot, SecondaryFooterSlotProps, } from "../footer/SecondaryFooterSlot.tsx"; -import { - DirectoryCard, - DirectoryCardProps, -} from "../directory/DirectoryCard.tsx"; -import { - DirectoryGrid, - DirectoryGridProps, -} from "../directory/DirectoryWrapper.tsx"; -import { Phone, PhoneProps } from "../contentBlocks/Phone.tsx"; -import { - BreadcrumbsSection, - BreadcrumbsSectionProps, -} from "../pageSections/Breadcrumbs.tsx"; +import { HeaderLinks, HeaderLinksProps } from "../header/HeaderLinks.tsx"; import { PrimaryHeaderSlot, PrimaryHeaderSlotProps, @@ -129,7 +73,67 @@ import { SecondaryHeaderSlot, SecondaryHeaderSlotProps, } from "../header/SecondaryHeaderSlot.tsx"; -import { HeaderLinks, HeaderLinksProps } from "../header/HeaderLinks.tsx"; +import { + AboutSectionDetailsColumn, + AboutSectionDetailsColumnProps, +} from "../pageSections/AboutSection/AboutSectionDetailsColumn.tsx"; +import { + BreadcrumbsSection, + BreadcrumbsSectionProps, +} from "../pageSections/Breadcrumbs.tsx"; +import { + EventCard, + EventCardProps, +} from "../pageSections/EventSection/EventCard.tsx"; +import { + EventCardsWrapper, + EventCardsWrapperProps, +} from "../pageSections/EventSection/EventCardsWrapper.tsx"; +import { FAQCard, FAQCardProps } from "../pageSections/FAQsSection/FAQCard.tsx"; +import { + InsightCard, + InsightCardProps, +} from "../pageSections/InsightSection/InsightCard.tsx"; +import { + InsightCardsWrapper, + InsightCardsWrapperProps, +} from "../pageSections/InsightSection/InsightCardsWrapper.tsx"; +import { + NearbyLocationCardsWrapper, + NearbyLocationCardsWrapperProps, +} from "../pageSections/NearbyLocations/NearbyLocationsCardsWrapper.tsx"; +import { + PhotoGalleryWrapper, + PhotoGalleryWrapperProps, +} from "../pageSections/PhotoGallerySection/PhotoGalleryWrapper.tsx"; +import { + ProductCard, + ProductCardProps, +} from "../pageSections/ProductSection/ProductCard.tsx"; +import { + ProductCardsWrapper, + ProductCardsWrapperProps, +} from "../pageSections/ProductSection/ProductCardsWrapper.tsx"; +import { + SearchBarSlot, + SearchBarSlotProps, +} from "../pageSections/SearchSection/SearchBarSlot.tsx"; +import { + TeamCard, + TeamCardProps, +} from "../pageSections/TeamSection/TeamCard.tsx"; +import { + TeamCardsWrapper, + TeamCardsWrapperProps, +} from "../pageSections/TeamSection/TeamCardsWrapper.tsx"; +import { + TestimonialCard, + TestimonialCardProps, +} from "../pageSections/TestimonialSection/TestimonialCard.tsx"; +import { + TestimonialCardsWrapper, + TestimonialCardsWrapperProps, +} from "../pageSections/TestimonialSection/TestimonialCardsWrapper.tsx"; export interface SlotsCategoryProps { AddressSlot: AddressProps; @@ -174,6 +178,7 @@ export interface SlotsCategoryProps { TextListSlot: TextListProps; Timestamp: TimestampProps; VideoSlot: VideoProps; + SearchBarSlot: SearchBarSlotProps; } const lockedPermissions = { @@ -269,6 +274,7 @@ export const SlotsCategoryComponents = { TextListSlot: { ...TextList, permissions: lockedPermissions }, Timestamp: { ...Timestamp, permissions: lockedPermissions }, VideoSlot: { ...Video, permissions: lockedPermissions }, + SearchBarSlot: { ...SearchBarSlot, permission: lockedPermissions }, }; export const SlotsCategory = Object.keys( diff --git a/packages/visual-editor/src/components/pageSections/SearchSection/Search.tsx b/packages/visual-editor/src/components/pageSections/SearchSection/Search.tsx new file mode 100644 index 0000000000..158d2bd436 --- /dev/null +++ b/packages/visual-editor/src/components/pageSections/SearchSection/Search.tsx @@ -0,0 +1,287 @@ +import { ComponentConfig, Fields, PuckComponent, Slot } from "@puckeditor/core"; +import { + CloudRegion, + Environment, + provideHeadless, + SearchConfig, + SearchHeadlessProvider, +} from "@yext/search-headless-react"; +import { + DefaultRawDataType, + SearchI18nextProvider, + SectionProps, + StandardCard, +} from "@yext/search-ui-react"; +import React from "react"; +import { YextField } from "../../../editor/YextField.tsx"; +import { useDocument } from "../../../hooks/useDocument.tsx"; +import { msg } from "../../../utils/index.ts"; +import { PageSection } from "../../atoms/pageSection.tsx"; +import { SearchBarSlotProps } from "./SearchBarSlot.tsx"; + +type VerticalLayout = "Grid" | "Flex" | "Map"; + +interface VerticalConfig { + label: string; + verticalKey: string; + layout: VerticalLayout; + universalLimit: number; + verticalLimit: number; +} + +export interface SearchComponentProps { + verticals: VerticalConfig[]; + /** @internal */ + slots: { + SearchBarSlot: Slot; + }; +} + +const locatorFields: Fields = { + verticals: { + label: msg("fields.verticals", "Verticals"), + type: "array", + arrayFields: { + label: YextField(msg("fields.label", "Label"), { type: "text" }), + + verticalKey: YextField(msg("fields.verticalKey", "Vertical Key"), { + type: "text", + }), + + layout: YextField(msg("fields.layout", "Layout"), { + type: "radio", + options: [ + { label: "Grid", value: "Grid" }, + { label: "Flex", value: "Flex" }, + { label: "Map", value: "Map" }, + ], + }), + + universalLimit: YextField( + msg("fields.universalLimit", "Universal Limit"), + { type: "number" } + ), + + verticalLimit: YextField(msg("fields.verticalLimit", "Vertical Limit"), { + type: "number", + }), + }, + getItemSummary: (item) => item?.label || "Vertical", + }, + slots: { + type: "object", + visible: false, + objectFields: { + SearchBarSlot: { type: "slot" }, + }, + }, +}; +const EXPERIENCE_VERSION = "PRODUCTION"; + +export const searchConfig: SearchConfig = { + apiKey: "fb73f1bf6a262bc3255bcb938088204f", + experienceKey: "ukg-fins", + locale: "en", + experienceVersion: EXPERIENCE_VERSION, + cloudRegion: CloudRegion.US, + environment: Environment.PROD, +}; + +const SearchWrapper: PuckComponent = ({ + verticals, + slots, + puck, +}) => { + const verticalConfigMap = React.useMemo( + () => buildVerticalConfigMap(verticals), + [verticals] + ); + + console.log(verticalConfigMap); + + const streamDocument = useDocument(); + const { searchAnalyticsConfig, searcher } = React.useMemo(() => { + const searchHeadlessConfig = provideHeadless(searchConfig); + if (searchHeadlessConfig === undefined) { + return { searchAnalyticsConfig: undefined, searcher: undefined }; + } + + const searchAnalyticsConfig = provideHeadless(searchConfig); + return { + searchAnalyticsConfig, + searcher: provideHeadless(searchConfig), + }; + }, [streamDocument.id, streamDocument.locale]); + + if (searcher === undefined || searchAnalyticsConfig === undefined) { + console.warn( + "Could not create Locator component because Search Headless or Search Analytics config is undefined. Please check your environment variables." + ); + return <>; + } + searcher.setSessionTrackingEnabled(true); + return ( + + + + + + + + ); +}; + +export const verticalConfigMap = { + faq: { + label: "FAQs", + viewAllButton: true, + CardComponent: StandardCard, + universalLimit: 3, + verticalLimit: 5, + }, + "financial-professional": { + label: "Professionals", + viewAllButton: true, + CardComponent: StandardCard, + universalLimit: 3, + verticalLimit: 5, + }, + + locations: { + label: "Locations", + viewAllButton: true, + CardComponent: StandardCard, + universalLimit: 3, + verticalLimit: 5, + }, + + jobs: { + label: "Jobs", + viewAllButton: true, + CardComponent: StandardCard, + universalLimit: 3, + verticalLimit: 5, + }, + + events: { + label: "Events", + viewAllButton: true, + CardComponent: StandardCard, + universalLimit: 3, + verticalLimit: 5, + }, + + product: { + label: "Products", + viewAllButton: true, + CardComponent: StandardCard, + universalLimit: 3, + verticalLimit: 5, + }, +}; + +// const SearchInternal = ({ verticals }: WithPuckProps) => { +// const verticalConfigMap = React.useMemo( +// () => buildVerticalConfigMap(verticals), +// [verticals] +// ); + +// return ( +// +// +// +// +// ); +// }; + +const buildVerticalConfigMap = (verticals: VerticalConfig[]) => { + const map: Record = {}; + + verticals.forEach((v) => { + const Section = (props: SectionProps) => ( + + ); + + map[v.verticalKey] = { + label: v.label, + viewAllButton: true, + SectionComponent: Section, + CardComponent: StandardCard, + universalLimit: v.universalLimit, + verticalLimit: v.verticalLimit, + }; + }); + + return map; +}; + +const SearchLayout = ({ + layout, + data: { results, CardComponent }, +}: { + layout: VerticalLayout; + data: SectionProps; +}) => { + if (!CardComponent) return null; + + const className = + layout === "Grid" + ? "grid grid-cols-3 gap-4 w-full" + : layout === "Flex" + ? "flex flex-col gap-4 w-full" + : "flex flex-col w-full"; + + return ( +
+ {results.map((r, i) => ( + + ))} +
+ ); +}; + +export const SearchComponent: ComponentConfig<{ + props: SearchComponentProps; +}> = { + label: msg("components.searchWithSlots", "Search with Slots"), + fields: locatorFields, + + defaultProps: { + verticals: [ + { + label: "FAQs", + verticalKey: "faq", + layout: "Flex", + universalLimit: 3, + verticalLimit: 5, + }, + { + label: "Products", + verticalKey: "product", + layout: "Grid", + universalLimit: 3, + verticalLimit: 5, + }, + { + label: "Locations", + verticalKey: "locations", + layout: "Map", + universalLimit: 3, + verticalLimit: 5, + }, + ], + slots: { + SearchBarSlot: [ + { + type: "SearchBarSlot", + props: { + styles: { + showIcon: false, + }, + } satisfies SearchBarSlotProps, + }, + ], + }, + }, + render: (props) => , +}; diff --git a/packages/visual-editor/src/components/pageSections/SearchSection/SearchBarSlot.tsx b/packages/visual-editor/src/components/pageSections/SearchSection/SearchBarSlot.tsx new file mode 100644 index 0000000000..f9ce445f1c --- /dev/null +++ b/packages/visual-editor/src/components/pageSections/SearchSection/SearchBarSlot.tsx @@ -0,0 +1,50 @@ +import { ComponentConfig, Fields, PuckComponent } from "@puckeditor/core"; +import { YextField } from "../../../editor/YextField.tsx"; +import { msg } from "../../../utils/index.ts"; + +export interface SearchBarSlotProps { + styles: { showIcon: boolean }; +} +const defaultSearchBarProps: SearchBarSlotProps = { + styles: { + showIcon: false, + }, +}; + +const searchBarSlotFields: Fields = { + styles: YextField(msg("fields.styles", "Styles"), { + type: "object", + objectFields: { + showIcon: YextField(msg("fields.showIcon", "Show Icon"), { + type: "radio", + options: [ + { label: msg("fields.options.show", "Show"), value: true }, + { label: msg("fields.options.hide", "Hide"), value: false }, + ], + }), + }, + }), +}; + +const SearchBarSlotInternal: PuckComponent = (props) => { + const { + styles: { showIcon = false }, + puck, + } = props; + console.log(showIcon); + if (puck.isEditing) { + return ( +
+ Search Bar +
+ ); + } + return
Search Slot
; +}; + +export const SearchBarSlot: ComponentConfig<{ props: SearchBarSlotProps }> = { + label: msg("components.searchBarSlot", "SearchBar Slot"), + fields: searchBarSlotFields, + defaultProps: defaultSearchBarProps, + render: (props) => , +}; diff --git a/packages/visual-editor/src/components/pageSections/index.ts b/packages/visual-editor/src/components/pageSections/index.ts index 2c559d1b2d..b0d31df388 100644 --- a/packages/visual-editor/src/components/pageSections/index.ts +++ b/packages/visual-editor/src/components/pageSections/index.ts @@ -90,3 +90,7 @@ export { ClassicSearchComponent, type ClassicSearchProps, } from "./SearchSectionClassic/ClassicSearch.tsx"; +export { + SearchComponent, + type SearchComponentProps, +} from "./SearchSection/Search.tsx"; From 10a100a9e5a278dfc49ed34dd9db30fc301cd26c Mon Sep 17 00:00:00 2001 From: rkeerthient Date: Fri, 6 Feb 2026 15:43:19 +0530 Subject: [PATCH 07/90] working code --- .../components/categories/SlotsCategory.tsx | 6 +++ .../pageSections/SearchSection/Search.tsx | 14 ++++- .../SearchSection/SearchResultsSlot.tsx | 54 +++++++++++++++++++ 3 files changed, 73 insertions(+), 1 deletion(-) create mode 100644 packages/visual-editor/src/components/pageSections/SearchSection/SearchResultsSlot.tsx diff --git a/packages/visual-editor/src/components/categories/SlotsCategory.tsx b/packages/visual-editor/src/components/categories/SlotsCategory.tsx index 5b7adfaa36..cb0fc26be7 100644 --- a/packages/visual-editor/src/components/categories/SlotsCategory.tsx +++ b/packages/visual-editor/src/components/categories/SlotsCategory.tsx @@ -118,6 +118,10 @@ import { SearchBarSlot, SearchBarSlotProps, } from "../pageSections/SearchSection/SearchBarSlot.tsx"; +import { + SearchResultsSlot, + SearchResultsSlotProps, +} from "../pageSections/SearchSection/SearchResultsSlot.tsx"; import { TeamCard, TeamCardProps, @@ -179,6 +183,7 @@ export interface SlotsCategoryProps { Timestamp: TimestampProps; VideoSlot: VideoProps; SearchBarSlot: SearchBarSlotProps; + SearchResultsSlot: SearchResultsSlotProps; } const lockedPermissions = { @@ -275,6 +280,7 @@ export const SlotsCategoryComponents = { Timestamp: { ...Timestamp, permissions: lockedPermissions }, VideoSlot: { ...Video, permissions: lockedPermissions }, SearchBarSlot: { ...SearchBarSlot, permission: lockedPermissions }, + SearchResultsSlot: { ...SearchResultsSlot, permission: lockedPermissions }, }; export const SlotsCategory = Object.keys( diff --git a/packages/visual-editor/src/components/pageSections/SearchSection/Search.tsx b/packages/visual-editor/src/components/pageSections/SearchSection/Search.tsx index 158d2bd436..e8d1bbf755 100644 --- a/packages/visual-editor/src/components/pageSections/SearchSection/Search.tsx +++ b/packages/visual-editor/src/components/pageSections/SearchSection/Search.tsx @@ -34,6 +34,7 @@ export interface SearchComponentProps { /** @internal */ slots: { SearchBarSlot: Slot; + SearchResultsSlot: Slot; }; } @@ -73,6 +74,7 @@ const locatorFields: Fields = { visible: false, objectFields: { SearchBarSlot: { type: "slot" }, + SearchResultsSlot: { type: "slot" }, }, }, }; @@ -96,7 +98,6 @@ const SearchWrapper: PuckComponent = ({ () => buildVerticalConfigMap(verticals), [verticals] ); - console.log(verticalConfigMap); const streamDocument = useDocument(); @@ -125,6 +126,7 @@ const SearchWrapper: PuckComponent = ({ + @@ -281,6 +283,16 @@ export const SearchComponent: ComponentConfig<{ } satisfies SearchBarSlotProps, }, ], + SearchResultsSlot: [ + { + type: "SearchBarSlot", + props: { + styles: { + showIcon: false, + }, + } satisfies SearchBarSlotProps, + }, + ], }, }, render: (props) => , diff --git a/packages/visual-editor/src/components/pageSections/SearchSection/SearchResultsSlot.tsx b/packages/visual-editor/src/components/pageSections/SearchSection/SearchResultsSlot.tsx new file mode 100644 index 0000000000..e92128eb4d --- /dev/null +++ b/packages/visual-editor/src/components/pageSections/SearchSection/SearchResultsSlot.tsx @@ -0,0 +1,54 @@ +import { ComponentConfig, Fields, PuckComponent } from "@puckeditor/core"; +import { YextField } from "../../../editor/YextField.tsx"; +import { msg } from "../../../utils/index.ts"; + +export interface SearchResultsSlotProps { + styles: { showIcon: boolean }; +} +const defaultSearchResultsProps: SearchResultsSlotProps = { + styles: { + showIcon: false, + }, +}; + +const SearchResultsSlotFields: Fields = { + styles: YextField(msg("fields.styles", "Styles"), { + type: "object", + objectFields: { + showIcon: YextField(msg("fields.showIcon", "Show Icon"), { + type: "radio", + options: [ + { label: msg("fields.options.show", "Show"), value: true }, + { label: msg("fields.options.hide", "Hide"), value: false }, + ], + }), + }, + }), +}; + +const SearchResultsSlotInternal: PuckComponent = ( + props +) => { + const { + styles: { showIcon = false }, + puck, + } = props; + console.log(showIcon); + if (puck.isEditing) { + return ( +
+ Search Bar +
+ ); + } + return
Search Result
; +}; + +export const SearchResultsSlot: ComponentConfig<{ + props: SearchResultsSlotProps; +}> = { + label: msg("components.SearchResultsSlot", "Search Results Slot"), + fields: SearchResultsSlotFields, + defaultProps: defaultSearchResultsProps, + render: (props) => , +}; From c45dcb10abd085d050beda2cbb9495f7f4ace59e Mon Sep 17 00:00:00 2001 From: rkeerthient Date: Fri, 6 Feb 2026 16:18:15 +0530 Subject: [PATCH 08/90] updated key --- .../visual-editor/src/components/categories/SlotsCategory.tsx | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/visual-editor/src/components/categories/SlotsCategory.tsx b/packages/visual-editor/src/components/categories/SlotsCategory.tsx index cb0fc26be7..7b62057c20 100644 --- a/packages/visual-editor/src/components/categories/SlotsCategory.tsx +++ b/packages/visual-editor/src/components/categories/SlotsCategory.tsx @@ -279,8 +279,8 @@ export const SlotsCategoryComponents = { TextListSlot: { ...TextList, permissions: lockedPermissions }, Timestamp: { ...Timestamp, permissions: lockedPermissions }, VideoSlot: { ...Video, permissions: lockedPermissions }, - SearchBarSlot: { ...SearchBarSlot, permission: lockedPermissions }, - SearchResultsSlot: { ...SearchResultsSlot, permission: lockedPermissions }, + SearchBarSlot: { ...SearchBarSlot, permissions: lockedPermissions }, + SearchResultsSlot: { ...SearchResultsSlot, permissions: lockedPermissions }, }; export const SlotsCategory = Object.keys( From ebcae760d7c8588334e680c1e3dbf7157534a7e0 Mon Sep 17 00:00:00 2001 From: rkeerthient Date: Tue, 10 Feb 2026 01:09:15 +0530 Subject: [PATCH 09/90] temp commit --- .../pageSections/SearchSection/Search.tsx | 11 ------ .../SearchSection/SearchResultsSlot.tsx | 35 +++++++++++++++++++ 2 files changed, 35 insertions(+), 11 deletions(-) diff --git a/packages/visual-editor/src/components/pageSections/SearchSection/Search.tsx b/packages/visual-editor/src/components/pageSections/SearchSection/Search.tsx index e8d1bbf755..6ed9009ac8 100644 --- a/packages/visual-editor/src/components/pageSections/SearchSection/Search.tsx +++ b/packages/visual-editor/src/components/pageSections/SearchSection/Search.tsx @@ -19,18 +19,7 @@ import { msg } from "../../../utils/index.ts"; import { PageSection } from "../../atoms/pageSection.tsx"; import { SearchBarSlotProps } from "./SearchBarSlot.tsx"; -type VerticalLayout = "Grid" | "Flex" | "Map"; - -interface VerticalConfig { - label: string; - verticalKey: string; - layout: VerticalLayout; - universalLimit: number; - verticalLimit: number; -} - export interface SearchComponentProps { - verticals: VerticalConfig[]; /** @internal */ slots: { SearchBarSlot: Slot; diff --git a/packages/visual-editor/src/components/pageSections/SearchSection/SearchResultsSlot.tsx b/packages/visual-editor/src/components/pageSections/SearchSection/SearchResultsSlot.tsx index e92128eb4d..58446b7997 100644 --- a/packages/visual-editor/src/components/pageSections/SearchSection/SearchResultsSlot.tsx +++ b/packages/visual-editor/src/components/pageSections/SearchSection/SearchResultsSlot.tsx @@ -3,9 +3,44 @@ import { YextField } from "../../../editor/YextField.tsx"; import { msg } from "../../../utils/index.ts"; export interface SearchResultsSlotProps { + data: { verticals: VerticalConfig[] }; styles: { showIcon: boolean }; } +type VerticalLayout = "Grid" | "Flex" | "Map"; + +interface VerticalConfig { + label: string; + verticalKey: string; + layout: VerticalLayout; + universalLimit: number; + verticalLimit: number; +} const defaultSearchResultsProps: SearchResultsSlotProps = { + data: { + verticals: [ + { + label: "FAQs", + verticalKey: "faq", + layout: "Flex", + universalLimit: 3, + verticalLimit: 5, + }, + { + label: "Products", + verticalKey: "product", + layout: "Grid", + universalLimit: 3, + verticalLimit: 5, + }, + { + label: "Locations", + verticalKey: "locations", + layout: "Map", + universalLimit: 3, + verticalLimit: 5, + }, + ], + }, styles: { showIcon: false, }, From d2f7bbddb6a0499ab693a298739473f897e99488 Mon Sep 17 00:00:00 2001 From: rkeerthient Date: Tue, 10 Feb 2026 14:19:25 +0530 Subject: [PATCH 10/90] temp push --- .../pageSections/SearchSection/Search.tsx | 208 ++---------- .../SearchSection/SearchResultsSlot.tsx | 144 ++++++++- .../components/pageSections/SearchSection/_bu | 299 ++++++++++++++++++ 3 files changed, 467 insertions(+), 184 deletions(-) create mode 100644 packages/visual-editor/src/components/pageSections/SearchSection/_bu diff --git a/packages/visual-editor/src/components/pageSections/SearchSection/Search.tsx b/packages/visual-editor/src/components/pageSections/SearchSection/Search.tsx index 6ed9009ac8..e56167e793 100644 --- a/packages/visual-editor/src/components/pageSections/SearchSection/Search.tsx +++ b/packages/visual-editor/src/components/pageSections/SearchSection/Search.tsx @@ -6,18 +6,13 @@ import { SearchConfig, SearchHeadlessProvider, } from "@yext/search-headless-react"; -import { - DefaultRawDataType, - SearchI18nextProvider, - SectionProps, - StandardCard, -} from "@yext/search-ui-react"; +import { SearchI18nextProvider } from "@yext/search-ui-react"; import React from "react"; -import { YextField } from "../../../editor/YextField.tsx"; import { useDocument } from "../../../hooks/useDocument.tsx"; import { msg } from "../../../utils/index.ts"; import { PageSection } from "../../atoms/pageSection.tsx"; import { SearchBarSlotProps } from "./SearchBarSlot.tsx"; +import { SearchResultsSlotProps } from "./SearchResultsSlot.tsx"; export interface SearchComponentProps { /** @internal */ @@ -28,36 +23,6 @@ export interface SearchComponentProps { } const locatorFields: Fields = { - verticals: { - label: msg("fields.verticals", "Verticals"), - type: "array", - arrayFields: { - label: YextField(msg("fields.label", "Label"), { type: "text" }), - - verticalKey: YextField(msg("fields.verticalKey", "Vertical Key"), { - type: "text", - }), - - layout: YextField(msg("fields.layout", "Layout"), { - type: "radio", - options: [ - { label: "Grid", value: "Grid" }, - { label: "Flex", value: "Flex" }, - { label: "Map", value: "Map" }, - ], - }), - - universalLimit: YextField( - msg("fields.universalLimit", "Universal Limit"), - { type: "number" } - ), - - verticalLimit: YextField(msg("fields.verticalLimit", "Vertical Limit"), { - type: "number", - }), - }, - getItemSummary: (item) => item?.label || "Vertical", - }, slots: { type: "object", visible: false, @@ -79,16 +44,9 @@ export const searchConfig: SearchConfig = { }; const SearchWrapper: PuckComponent = ({ - verticals, slots, puck, }) => { - const verticalConfigMap = React.useMemo( - () => buildVerticalConfigMap(verticals), - [verticals] - ); - console.log(verticalConfigMap); - const streamDocument = useDocument(); const { searchAnalyticsConfig, searcher } = React.useMemo(() => { const searchHeadlessConfig = provideHeadless(searchConfig); @@ -122,145 +80,12 @@ const SearchWrapper: PuckComponent = ({ ); }; -export const verticalConfigMap = { - faq: { - label: "FAQs", - viewAllButton: true, - CardComponent: StandardCard, - universalLimit: 3, - verticalLimit: 5, - }, - "financial-professional": { - label: "Professionals", - viewAllButton: true, - CardComponent: StandardCard, - universalLimit: 3, - verticalLimit: 5, - }, - - locations: { - label: "Locations", - viewAllButton: true, - CardComponent: StandardCard, - universalLimit: 3, - verticalLimit: 5, - }, - - jobs: { - label: "Jobs", - viewAllButton: true, - CardComponent: StandardCard, - universalLimit: 3, - verticalLimit: 5, - }, - - events: { - label: "Events", - viewAllButton: true, - CardComponent: StandardCard, - universalLimit: 3, - verticalLimit: 5, - }, - - product: { - label: "Products", - viewAllButton: true, - CardComponent: StandardCard, - universalLimit: 3, - verticalLimit: 5, - }, -}; - -// const SearchInternal = ({ verticals }: WithPuckProps) => { -// const verticalConfigMap = React.useMemo( -// () => buildVerticalConfigMap(verticals), -// [verticals] -// ); - -// return ( -// -// -// -// -// ); -// }; - -const buildVerticalConfigMap = (verticals: VerticalConfig[]) => { - const map: Record = {}; - - verticals.forEach((v) => { - const Section = (props: SectionProps) => ( - - ); - - map[v.verticalKey] = { - label: v.label, - viewAllButton: true, - SectionComponent: Section, - CardComponent: StandardCard, - universalLimit: v.universalLimit, - verticalLimit: v.verticalLimit, - }; - }); - - return map; -}; - -const SearchLayout = ({ - layout, - data: { results, CardComponent }, -}: { - layout: VerticalLayout; - data: SectionProps; -}) => { - if (!CardComponent) return null; - - const className = - layout === "Grid" - ? "grid grid-cols-3 gap-4 w-full" - : layout === "Flex" - ? "flex flex-col gap-4 w-full" - : "flex flex-col w-full"; - - return ( -
- {results.map((r, i) => ( - - ))} -
- ); -}; - export const SearchComponent: ComponentConfig<{ props: SearchComponentProps; }> = { label: msg("components.searchWithSlots", "Search with Slots"), fields: locatorFields, - defaultProps: { - verticals: [ - { - label: "FAQs", - verticalKey: "faq", - layout: "Flex", - universalLimit: 3, - verticalLimit: 5, - }, - { - label: "Products", - verticalKey: "product", - layout: "Grid", - universalLimit: 3, - verticalLimit: 5, - }, - { - label: "Locations", - verticalKey: "locations", - layout: "Map", - universalLimit: 3, - verticalLimit: 5, - }, - ], slots: { SearchBarSlot: [ { @@ -274,12 +99,37 @@ export const SearchComponent: ComponentConfig<{ ], SearchResultsSlot: [ { - type: "SearchBarSlot", + type: "SearchResultsSlot", props: { + data: { + verticals: [ + { + label: "FAQs", + verticalKey: "faq", + layout: "Flex", + universalLimit: 3, + verticalLimit: 5, + }, + { + label: "Products", + verticalKey: "product", + layout: "Grid", + universalLimit: 3, + verticalLimit: 5, + }, + { + label: "Locations", + verticalKey: "locations", + layout: "Map", + universalLimit: 3, + verticalLimit: 5, + }, + ], + }, styles: { showIcon: false, }, - } satisfies SearchBarSlotProps, + } satisfies SearchResultsSlotProps, }, ], }, diff --git a/packages/visual-editor/src/components/pageSections/SearchSection/SearchResultsSlot.tsx b/packages/visual-editor/src/components/pageSections/SearchSection/SearchResultsSlot.tsx index 58446b7997..82d7fba290 100644 --- a/packages/visual-editor/src/components/pageSections/SearchSection/SearchResultsSlot.tsx +++ b/packages/visual-editor/src/components/pageSections/SearchSection/SearchResultsSlot.tsx @@ -1,4 +1,5 @@ import { ComponentConfig, Fields, PuckComponent } from "@puckeditor/core"; +import { StandardCard } from "@yext/search-ui-react"; import { YextField } from "../../../editor/YextField.tsx"; import { msg } from "../../../utils/index.ts"; @@ -15,6 +16,7 @@ interface VerticalConfig { universalLimit: number; verticalLimit: number; } + const defaultSearchResultsProps: SearchResultsSlotProps = { data: { verticals: [ @@ -45,8 +47,139 @@ const defaultSearchResultsProps: SearchResultsSlotProps = { showIcon: false, }, }; +export const verticalConfigMap = { + faq: { + label: "FAQs", + viewAllButton: true, + CardComponent: StandardCard, + universalLimit: 3, + verticalLimit: 5, + }, + "financial-professional": { + label: "Professionals", + viewAllButton: true, + CardComponent: StandardCard, + universalLimit: 3, + verticalLimit: 5, + }, + + locations: { + label: "Locations", + viewAllButton: true, + CardComponent: StandardCard, + universalLimit: 3, + verticalLimit: 5, + }, + + jobs: { + label: "Jobs", + viewAllButton: true, + CardComponent: StandardCard, + universalLimit: 3, + verticalLimit: 5, + }, + + events: { + label: "Events", + viewAllButton: true, + CardComponent: StandardCard, + universalLimit: 3, + verticalLimit: 5, + }, + + product: { + label: "Products", + viewAllButton: true, + CardComponent: StandardCard, + universalLimit: 3, + verticalLimit: 5, + }, +}; +// const buildVerticalConfigMap = (verticals: VerticalConfig[]) => { +// const map: Record = {}; + +// verticals.forEach((v) => { +// const Section = (props: SectionProps) => ( +// +// ); + +// map[v.verticalKey] = { +// label: v.label, +// viewAllButton: true, +// SectionComponent: Section, +// CardComponent: StandardCard, +// universalLimit: v.universalLimit, +// verticalLimit: v.verticalLimit, +// }; +// }); + +// return map; +// }; + +// const SearchLayout = ({ +// layout, +// data: { results, CardComponent }, +// }: { +// layout: VerticalLayout; +// data: SectionProps; +// }) => { +// if (!CardComponent) return null; + +// const className = +// layout === "Grid" +// ? "grid grid-cols-3 gap-4 w-full" +// : layout === "Flex" +// ? "flex flex-col gap-4 w-full" +// : "flex flex-col w-full"; + +// return ( +//
+// {results.map((r, i) => ( +// +// ))} +//
+// ); +// }; const SearchResultsSlotFields: Fields = { + data: YextField(msg("fields.data", "Data"), { + type: "object", + objectFields: { + verticals: { + label: msg("fields.verticals", "Verticals"), + type: "array", + arrayFields: { + label: YextField(msg("fields.label", "Label"), { type: "text" }), + + verticalKey: YextField(msg("fields.verticalKey", "Vertical Key"), { + type: "text", + }), + + layout: YextField(msg("fields.layout", "Layout"), { + type: "radio", + options: [ + { label: "Grid", value: "Grid" }, + { label: "Flex", value: "Flex" }, + { label: "Map", value: "Map" }, + ], + }), + + universalLimit: YextField( + msg("fields.universalLimit", "Universal Limit"), + { type: "number" } + ), + + verticalLimit: YextField( + msg("fields.verticalLimit", "Vertical Limit"), + { + type: "number", + } + ), + }, + getItemSummary: (item) => item?.label || "Vertical", + }, + }, + }), styles: YextField(msg("fields.styles", "Styles"), { type: "object", objectFields: { @@ -64,11 +197,12 @@ const SearchResultsSlotFields: Fields = { const SearchResultsSlotInternal: PuckComponent = ( props ) => { - const { - styles: { showIcon = false }, - puck, - } = props; - console.log(showIcon); + const { puck } = props; + // const verticalConfigMap = React.useMemo( + // () => buildVerticalConfigMap(verticals), + // [verticals] + // ); + if (puck.isEditing) { return (
diff --git a/packages/visual-editor/src/components/pageSections/SearchSection/_bu b/packages/visual-editor/src/components/pageSections/SearchSection/_bu new file mode 100644 index 0000000000..e8d1bbf755 --- /dev/null +++ b/packages/visual-editor/src/components/pageSections/SearchSection/_bu @@ -0,0 +1,299 @@ +import { ComponentConfig, Fields, PuckComponent, Slot } from "@puckeditor/core"; +import { + CloudRegion, + Environment, + provideHeadless, + SearchConfig, + SearchHeadlessProvider, +} from "@yext/search-headless-react"; +import { + DefaultRawDataType, + SearchI18nextProvider, + SectionProps, + StandardCard, +} from "@yext/search-ui-react"; +import React from "react"; +import { YextField } from "../../../editor/YextField.tsx"; +import { useDocument } from "../../../hooks/useDocument.tsx"; +import { msg } from "../../../utils/index.ts"; +import { PageSection } from "../../atoms/pageSection.tsx"; +import { SearchBarSlotProps } from "./SearchBarSlot.tsx"; + +type VerticalLayout = "Grid" | "Flex" | "Map"; + +interface VerticalConfig { + label: string; + verticalKey: string; + layout: VerticalLayout; + universalLimit: number; + verticalLimit: number; +} + +export interface SearchComponentProps { + verticals: VerticalConfig[]; + /** @internal */ + slots: { + SearchBarSlot: Slot; + SearchResultsSlot: Slot; + }; +} + +const locatorFields: Fields = { + verticals: { + label: msg("fields.verticals", "Verticals"), + type: "array", + arrayFields: { + label: YextField(msg("fields.label", "Label"), { type: "text" }), + + verticalKey: YextField(msg("fields.verticalKey", "Vertical Key"), { + type: "text", + }), + + layout: YextField(msg("fields.layout", "Layout"), { + type: "radio", + options: [ + { label: "Grid", value: "Grid" }, + { label: "Flex", value: "Flex" }, + { label: "Map", value: "Map" }, + ], + }), + + universalLimit: YextField( + msg("fields.universalLimit", "Universal Limit"), + { type: "number" } + ), + + verticalLimit: YextField(msg("fields.verticalLimit", "Vertical Limit"), { + type: "number", + }), + }, + getItemSummary: (item) => item?.label || "Vertical", + }, + slots: { + type: "object", + visible: false, + objectFields: { + SearchBarSlot: { type: "slot" }, + SearchResultsSlot: { type: "slot" }, + }, + }, +}; +const EXPERIENCE_VERSION = "PRODUCTION"; + +export const searchConfig: SearchConfig = { + apiKey: "fb73f1bf6a262bc3255bcb938088204f", + experienceKey: "ukg-fins", + locale: "en", + experienceVersion: EXPERIENCE_VERSION, + cloudRegion: CloudRegion.US, + environment: Environment.PROD, +}; + +const SearchWrapper: PuckComponent = ({ + verticals, + slots, + puck, +}) => { + const verticalConfigMap = React.useMemo( + () => buildVerticalConfigMap(verticals), + [verticals] + ); + console.log(verticalConfigMap); + + const streamDocument = useDocument(); + const { searchAnalyticsConfig, searcher } = React.useMemo(() => { + const searchHeadlessConfig = provideHeadless(searchConfig); + if (searchHeadlessConfig === undefined) { + return { searchAnalyticsConfig: undefined, searcher: undefined }; + } + + const searchAnalyticsConfig = provideHeadless(searchConfig); + return { + searchAnalyticsConfig, + searcher: provideHeadless(searchConfig), + }; + }, [streamDocument.id, streamDocument.locale]); + + if (searcher === undefined || searchAnalyticsConfig === undefined) { + console.warn( + "Could not create Locator component because Search Headless or Search Analytics config is undefined. Please check your environment variables." + ); + return <>; + } + searcher.setSessionTrackingEnabled(true); + return ( + + + + + + + + + ); +}; + +export const verticalConfigMap = { + faq: { + label: "FAQs", + viewAllButton: true, + CardComponent: StandardCard, + universalLimit: 3, + verticalLimit: 5, + }, + "financial-professional": { + label: "Professionals", + viewAllButton: true, + CardComponent: StandardCard, + universalLimit: 3, + verticalLimit: 5, + }, + + locations: { + label: "Locations", + viewAllButton: true, + CardComponent: StandardCard, + universalLimit: 3, + verticalLimit: 5, + }, + + jobs: { + label: "Jobs", + viewAllButton: true, + CardComponent: StandardCard, + universalLimit: 3, + verticalLimit: 5, + }, + + events: { + label: "Events", + viewAllButton: true, + CardComponent: StandardCard, + universalLimit: 3, + verticalLimit: 5, + }, + + product: { + label: "Products", + viewAllButton: true, + CardComponent: StandardCard, + universalLimit: 3, + verticalLimit: 5, + }, +}; + +// const SearchInternal = ({ verticals }: WithPuckProps) => { +// const verticalConfigMap = React.useMemo( +// () => buildVerticalConfigMap(verticals), +// [verticals] +// ); + +// return ( +// +// +// +// +// ); +// }; + +const buildVerticalConfigMap = (verticals: VerticalConfig[]) => { + const map: Record = {}; + + verticals.forEach((v) => { + const Section = (props: SectionProps) => ( + + ); + + map[v.verticalKey] = { + label: v.label, + viewAllButton: true, + SectionComponent: Section, + CardComponent: StandardCard, + universalLimit: v.universalLimit, + verticalLimit: v.verticalLimit, + }; + }); + + return map; +}; + +const SearchLayout = ({ + layout, + data: { results, CardComponent }, +}: { + layout: VerticalLayout; + data: SectionProps; +}) => { + if (!CardComponent) return null; + + const className = + layout === "Grid" + ? "grid grid-cols-3 gap-4 w-full" + : layout === "Flex" + ? "flex flex-col gap-4 w-full" + : "flex flex-col w-full"; + + return ( +
+ {results.map((r, i) => ( + + ))} +
+ ); +}; + +export const SearchComponent: ComponentConfig<{ + props: SearchComponentProps; +}> = { + label: msg("components.searchWithSlots", "Search with Slots"), + fields: locatorFields, + + defaultProps: { + verticals: [ + { + label: "FAQs", + verticalKey: "faq", + layout: "Flex", + universalLimit: 3, + verticalLimit: 5, + }, + { + label: "Products", + verticalKey: "product", + layout: "Grid", + universalLimit: 3, + verticalLimit: 5, + }, + { + label: "Locations", + verticalKey: "locations", + layout: "Map", + universalLimit: 3, + verticalLimit: 5, + }, + ], + slots: { + SearchBarSlot: [ + { + type: "SearchBarSlot", + props: { + styles: { + showIcon: false, + }, + } satisfies SearchBarSlotProps, + }, + ], + SearchResultsSlot: [ + { + type: "SearchBarSlot", + props: { + styles: { + showIcon: false, + }, + } satisfies SearchBarSlotProps, + }, + ], + }, + }, + render: (props) => , +}; From 3ce11cbe4ae7067c728ffa0e7276f7f58513b690 Mon Sep 17 00:00:00 2001 From: rkeerthient Date: Tue, 10 Feb 2026 16:08:36 +0530 Subject: [PATCH 11/90] working search OOTB --- .../pageSections/SearchSection/Search.tsx | 3 +- .../SearchSection/SearchResultsSlot.tsx | 134 ++++++++++++++++-- 2 files changed, 123 insertions(+), 14 deletions(-) diff --git a/packages/visual-editor/src/components/pageSections/SearchSection/Search.tsx b/packages/visual-editor/src/components/pageSections/SearchSection/Search.tsx index e56167e793..9c9abb7426 100644 --- a/packages/visual-editor/src/components/pageSections/SearchSection/Search.tsx +++ b/packages/visual-editor/src/components/pageSections/SearchSection/Search.tsx @@ -25,7 +25,6 @@ export interface SearchComponentProps { const locatorFields: Fields = { slots: { type: "object", - visible: false, objectFields: { SearchBarSlot: { type: "slot" }, SearchResultsSlot: { type: "slot" }, @@ -71,7 +70,7 @@ const SearchWrapper: PuckComponent = ({ return ( - + diff --git a/packages/visual-editor/src/components/pageSections/SearchSection/SearchResultsSlot.tsx b/packages/visual-editor/src/components/pageSections/SearchSection/SearchResultsSlot.tsx index 82d7fba290..1bfc4c9cae 100644 --- a/packages/visual-editor/src/components/pageSections/SearchSection/SearchResultsSlot.tsx +++ b/packages/visual-editor/src/components/pageSections/SearchSection/SearchResultsSlot.tsx @@ -1,7 +1,16 @@ import { ComponentConfig, Fields, PuckComponent } from "@puckeditor/core"; -import { StandardCard } from "@yext/search-ui-react"; +import { + DefaultRawDataType, + StandardCard, + StandardSection, + UniversalResults, + VerticalConfigMap, +} from "@yext/search-ui-react"; import { YextField } from "../../../editor/YextField.tsx"; import { msg } from "../../../utils/index.ts"; +import React from "react"; +import { useSearchActions } from "@yext/search-headless-react"; +import { FaEllipsisV } from "react-icons/fa"; export interface SearchResultsSlotProps { data: { verticals: VerticalConfig[] }; @@ -194,23 +203,124 @@ const SearchResultsSlotFields: Fields = { }), }; -const SearchResultsSlotInternal: PuckComponent = ( - props -) => { - const { puck } = props; +export const VerticalConfig = [ + { + label: "All", + pageType: "universal", + }, + { + label: "FAQs", + verticalKey: "faq", + pageType: "standard", + cardType: StandardCard, + universalLimit: 3, + verticalLimit: 5, + }, + { + label: "Professionals", + verticalKey: "financial-professional", + pageType: "grid-cols-3", + cardType: StandardCard, + universalLimit: 3, + verticalLimit: 5, + }, + { + label: "Locations", + verticalKey: "locations", + pageType: "map", + cardType: StandardCard, + universalLimit: 3, + verticalLimit: 5, + }, + { + label: "Jobs", + verticalKey: "jobs", + pageType: "standard", + cardType: StandardCard, + universalLimit: 3, + verticalLimit: 5, + }, + { + label: "Events", + verticalKey: "events", + pageType: "standard", + cardType: StandardCard, + universalLimit: 3, + verticalLimit: 5, + }, + { + label: "Products", + verticalKey: "product", + pageType: "grid-cols-3", + cardType: StandardCard, + universalLimit: 3, + verticalLimit: 5, + sortFields: ["name"], // ["fieldName, Ascending Label, Descending Label"] examples: ["name, Name (A-Z), Name (Z-A)"] or ["name, Name (A-Z), Name (Z-A)", "price.value, Price (Low - High), Price (High - Low)"] + }, +]; + +export const UniversalConfig: VerticalConfigMap< + Record +> = VerticalConfig.reduce( + (configMap, item) => { + if (item.verticalKey) { + configMap[item.verticalKey] = { + CardComponent: item.cardType, + SectionComponent: StandardSection, + label: item.label, + }; + } + return configMap; + }, + {} as VerticalConfigMap> +); + +const SearchResultsSlotInternal: PuckComponent = () => { + const searchActions = useSearchActions(); + React.useEffect(() => { + searchActions + .executeUniversalQuery() + .then((res) => console.log(JSON.stringify(res))); + }, []); + // const verticalConfigMap = React.useMemo( // () => buildVerticalConfigMap(verticals), // [verticals] // ); - if (puck.isEditing) { - return ( -
- Search Bar + return ( +
+
+ +
+ +
+
+
+
- ); - } - return
Search Result
; +
+ ); + // return
Search Result
; }; export const SearchResultsSlot: ComponentConfig<{ From 84e9c130eb352832b7c1158e179f8b27aa43ab24 Mon Sep 17 00:00:00 2001 From: rkeerthient Date: Wed, 11 Feb 2026 01:36:58 +0530 Subject: [PATCH 12/90] working model --- .../SearchSection/GridSection.tsx | 19 ++ .../pageSections/SearchSection/Search.tsx | 18 +- .../SearchSection/SearchResultsSlot.tsx | 289 ++++-------------- .../SearchSection/propsAndTypes.ts | 43 +++ .../pageSections/SearchSection/utils.tsx | 70 +++++ 5 files changed, 187 insertions(+), 252 deletions(-) create mode 100644 packages/visual-editor/src/components/pageSections/SearchSection/GridSection.tsx create mode 100644 packages/visual-editor/src/components/pageSections/SearchSection/propsAndTypes.ts create mode 100644 packages/visual-editor/src/components/pageSections/SearchSection/utils.tsx diff --git a/packages/visual-editor/src/components/pageSections/SearchSection/GridSection.tsx b/packages/visual-editor/src/components/pageSections/SearchSection/GridSection.tsx new file mode 100644 index 0000000000..e18c9fa3c1 --- /dev/null +++ b/packages/visual-editor/src/components/pageSections/SearchSection/GridSection.tsx @@ -0,0 +1,19 @@ +import React from "react"; +import { DefaultRawDataType, SectionProps } from "@yext/search-ui-react"; + +export const GridSection = ({ + results, + CardComponent, +}: SectionProps) => { + if (!results || !results.length || !CardComponent) { + return null; + } + + return ( +
+ {results.map((result, index) => ( + + ))} +
+ ); +}; diff --git a/packages/visual-editor/src/components/pageSections/SearchSection/Search.tsx b/packages/visual-editor/src/components/pageSections/SearchSection/Search.tsx index 9c9abb7426..41a0efcc1e 100644 --- a/packages/visual-editor/src/components/pageSections/SearchSection/Search.tsx +++ b/packages/visual-editor/src/components/pageSections/SearchSection/Search.tsx @@ -102,6 +102,10 @@ export const SearchComponent: ComponentConfig<{ props: { data: { verticals: [ + { + label: "All", + pageType: "universal", + }, { label: "FAQs", verticalKey: "faq", @@ -109,20 +113,6 @@ export const SearchComponent: ComponentConfig<{ universalLimit: 3, verticalLimit: 5, }, - { - label: "Products", - verticalKey: "product", - layout: "Grid", - universalLimit: 3, - verticalLimit: 5, - }, - { - label: "Locations", - verticalKey: "locations", - layout: "Map", - universalLimit: 3, - verticalLimit: 5, - }, ], }, styles: { diff --git a/packages/visual-editor/src/components/pageSections/SearchSection/SearchResultsSlot.tsx b/packages/visual-editor/src/components/pageSections/SearchSection/SearchResultsSlot.tsx index 1bfc4c9cae..6d95e85819 100644 --- a/packages/visual-editor/src/components/pageSections/SearchSection/SearchResultsSlot.tsx +++ b/packages/visual-editor/src/components/pageSections/SearchSection/SearchResultsSlot.tsx @@ -1,155 +1,20 @@ import { ComponentConfig, Fields, PuckComponent } from "@puckeditor/core"; -import { - DefaultRawDataType, - StandardCard, - StandardSection, - UniversalResults, - VerticalConfigMap, -} from "@yext/search-ui-react"; -import { YextField } from "../../../editor/YextField.tsx"; -import { msg } from "../../../utils/index.ts"; +import { useSearchActions, useSearchState } from "@yext/search-headless-react"; +import { UniversalResults } from "@yext/search-ui-react"; import React from "react"; -import { useSearchActions } from "@yext/search-headless-react"; import { FaEllipsisV } from "react-icons/fa"; - +import { YextField } from "../../../editor/YextField.tsx"; +import { msg } from "../../../utils/index.ts"; +import { defaultSearchResultsProps, VerticalConfig } from "./propsAndTypes.ts"; +import { + buildUniversalLimit, + buildVerticalConfigMap, + isValidVerticalConfig, +} from "./utils.tsx"; export interface SearchResultsSlotProps { data: { verticals: VerticalConfig[] }; styles: { showIcon: boolean }; } -type VerticalLayout = "Grid" | "Flex" | "Map"; - -interface VerticalConfig { - label: string; - verticalKey: string; - layout: VerticalLayout; - universalLimit: number; - verticalLimit: number; -} - -const defaultSearchResultsProps: SearchResultsSlotProps = { - data: { - verticals: [ - { - label: "FAQs", - verticalKey: "faq", - layout: "Flex", - universalLimit: 3, - verticalLimit: 5, - }, - { - label: "Products", - verticalKey: "product", - layout: "Grid", - universalLimit: 3, - verticalLimit: 5, - }, - { - label: "Locations", - verticalKey: "locations", - layout: "Map", - universalLimit: 3, - verticalLimit: 5, - }, - ], - }, - styles: { - showIcon: false, - }, -}; -export const verticalConfigMap = { - faq: { - label: "FAQs", - viewAllButton: true, - CardComponent: StandardCard, - universalLimit: 3, - verticalLimit: 5, - }, - "financial-professional": { - label: "Professionals", - viewAllButton: true, - CardComponent: StandardCard, - universalLimit: 3, - verticalLimit: 5, - }, - - locations: { - label: "Locations", - viewAllButton: true, - CardComponent: StandardCard, - universalLimit: 3, - verticalLimit: 5, - }, - - jobs: { - label: "Jobs", - viewAllButton: true, - CardComponent: StandardCard, - universalLimit: 3, - verticalLimit: 5, - }, - - events: { - label: "Events", - viewAllButton: true, - CardComponent: StandardCard, - universalLimit: 3, - verticalLimit: 5, - }, - - product: { - label: "Products", - viewAllButton: true, - CardComponent: StandardCard, - universalLimit: 3, - verticalLimit: 5, - }, -}; -// const buildVerticalConfigMap = (verticals: VerticalConfig[]) => { -// const map: Record = {}; - -// verticals.forEach((v) => { -// const Section = (props: SectionProps) => ( -// -// ); - -// map[v.verticalKey] = { -// label: v.label, -// viewAllButton: true, -// SectionComponent: Section, -// CardComponent: StandardCard, -// universalLimit: v.universalLimit, -// verticalLimit: v.verticalLimit, -// }; -// }); - -// return map; -// }; - -// const SearchLayout = ({ -// layout, -// data: { results, CardComponent }, -// }: { -// layout: VerticalLayout; -// data: SectionProps; -// }) => { -// if (!CardComponent) return null; - -// const className = -// layout === "Grid" -// ? "grid grid-cols-3 gap-4 w-full" -// : layout === "Flex" -// ? "flex flex-col gap-4 w-full" -// : "flex flex-col w-full"; - -// return ( -//
-// {results.map((r, i) => ( -// -// ))} -//
-// ); -// }; - const SearchResultsSlotFields: Fields = { data: YextField(msg("fields.data", "Data"), { type: "object", @@ -203,104 +68,52 @@ const SearchResultsSlotFields: Fields = { }), }; -export const VerticalConfig = [ - { - label: "All", - pageType: "universal", - }, - { - label: "FAQs", - verticalKey: "faq", - pageType: "standard", - cardType: StandardCard, - universalLimit: 3, - verticalLimit: 5, - }, - { - label: "Professionals", - verticalKey: "financial-professional", - pageType: "grid-cols-3", - cardType: StandardCard, - universalLimit: 3, - verticalLimit: 5, - }, - { - label: "Locations", - verticalKey: "locations", - pageType: "map", - cardType: StandardCard, - universalLimit: 3, - verticalLimit: 5, - }, - { - label: "Jobs", - verticalKey: "jobs", - pageType: "standard", - cardType: StandardCard, - universalLimit: 3, - verticalLimit: 5, - }, - { - label: "Events", - verticalKey: "events", - pageType: "standard", - cardType: StandardCard, - universalLimit: 3, - verticalLimit: 5, - }, - { - label: "Products", - verticalKey: "product", - pageType: "grid-cols-3", - cardType: StandardCard, - universalLimit: 3, - verticalLimit: 5, - sortFields: ["name"], // ["fieldName, Ascending Label, Descending Label"] examples: ["name, Name (A-Z), Name (Z-A)"] or ["name, Name (A-Z), Name (Z-A)", "price.value, Price (Low - High), Price (High - Low)"] - }, -]; +const SearchResultsSlotInternal: PuckComponent = ( + props +) => { + const { + data: { verticals }, + } = props; -export const UniversalConfig: VerticalConfigMap< - Record -> = VerticalConfig.reduce( - (configMap, item) => { - if (item.verticalKey) { - configMap[item.verticalKey] = { - CardComponent: item.cardType, - SectionComponent: StandardSection, - label: item.label, - }; - } - return configMap; - }, - {} as VerticalConfigMap> -); - -const SearchResultsSlotInternal: PuckComponent = () => { const searchActions = useSearchActions(); + const isLoading = useSearchState((s) => s.searchStatus.isLoading); + const searchTerm = useSearchState((s) => s.query.input) ?? " "; + const verticalConfigMap = React.useMemo( + () => buildVerticalConfigMap(verticals), + [verticals] + ); + + const universalLimit = React.useMemo( + () => buildUniversalLimit(verticals), + [verticals] + ); + React.useEffect(() => { - searchActions - .executeUniversalQuery() - .then((res) => console.log(JSON.stringify(res))); - }, []); + if (!isValidVerticalConfig(verticals)) { + console.warn("Skipping search: invalid vertical config", verticals); + return; + } - // const verticalConfigMap = React.useMemo( - // () => buildVerticalConfigMap(verticals), - // [verticals] - // ); + searchActions.setUniversal(); + searchActions.setQuery(searchTerm); + searchActions.setRestrictVerticals( + verticals.filter((v) => v.verticalKey).map((v) => v.verticalKey as string) + ); + searchActions.setUniversalLimit(universalLimit); + searchActions.executeUniversalQuery(); + }, [verticals, searchTerm, universalLimit, searchActions]); return (
-
+ + {!isLoading && ( -
+ )}
); - // return
Search Result
; }; export const SearchResultsSlot: ComponentConfig<{ diff --git a/packages/visual-editor/src/components/pageSections/SearchSection/propsAndTypes.ts b/packages/visual-editor/src/components/pageSections/SearchSection/propsAndTypes.ts new file mode 100644 index 0000000000..e16e6f59ae --- /dev/null +++ b/packages/visual-editor/src/components/pageSections/SearchSection/propsAndTypes.ts @@ -0,0 +1,43 @@ +import { SearchResultsSlotProps } from "./SearchResultsSlot.tsx"; + +export type VerticalLayout = "Grid" | "Flex" | "Map"; + +export interface VerticalConfig { + label: string; + verticalKey?: string; + layout?: VerticalLayout; + universalLimit?: number; + verticalLimit?: number; + pageType?: "universal" | "vertical"; +} + +export const defaultSearchResultsProps: SearchResultsSlotProps = { + data: { + verticals: [ + { + label: "FAQs", + verticalKey: "faq", + layout: "Flex", + universalLimit: 3, + verticalLimit: 5, + }, + { + label: "Products", + verticalKey: "product", + layout: "Grid", + universalLimit: 3, + verticalLimit: 5, + }, + { + label: "Locations", + verticalKey: "locations", + layout: "Map", + universalLimit: 3, + verticalLimit: 5, + }, + ], + }, + styles: { + showIcon: false, + }, +}; diff --git a/packages/visual-editor/src/components/pageSections/SearchSection/utils.tsx b/packages/visual-editor/src/components/pageSections/SearchSection/utils.tsx new file mode 100644 index 0000000000..28e986bf0a --- /dev/null +++ b/packages/visual-editor/src/components/pageSections/SearchSection/utils.tsx @@ -0,0 +1,70 @@ +import { UniversalLimit } from "@yext/search-headless-react"; +import { + DefaultRawDataType, + StandardCard, + StandardSection, + VerticalConfigMap, +} from "@yext/search-ui-react"; + +export const buildVerticalConfigMap = ( + verticals: { + label: string; + verticalKey?: string; + layout?: "Grid" | "Flex" | "Map"; + }[] +): VerticalConfigMap> => { + return verticals.reduce( + (acc, v) => { + if (!v.verticalKey) return acc; + + acc[v.verticalKey] = { + label: v.label, + viewAllButton: true, + SectionComponent: StandardSection, + CardComponent: StandardCard, + }; + + return acc; + }, + {} as VerticalConfigMap> + ); +}; + +export const buildUniversalLimit = ( + verticals: { + label: string; + verticalKey?: string; + universalLimit?: number; + }[] +): UniversalLimit => { + return verticals.reduce((acc, v) => { + if (!v.verticalKey || typeof v.universalLimit !== "number") { + return acc; + } + + acc[v.verticalKey] = v.universalLimit; + return acc; + }, {}); +}; + +const isValidVertical = (v: any): boolean => { + if (!v || typeof v !== "object") return false; + if (v.pageType === "universal") { + return typeof v.label === "string"; + } + return ( + typeof v.label === "string" && + typeof v.verticalKey === "string" && + (v.layout === "Grid" || v.layout === "Flex" || v.layout === "Map") && + typeof v.universalLimit === "number" && + typeof v.verticalLimit === "number" + ); +}; + +export const isValidVerticalConfig = (verticals: any[]): boolean => { + return ( + Array.isArray(verticals) && + verticals.length > 0 && + verticals.every(isValidVertical) + ); +}; From 43d446bec123871c638c9ab456809d1e968a2847 Mon Sep 17 00:00:00 2001 From: rkeerthient Date: Wed, 11 Feb 2026 02:01:56 +0530 Subject: [PATCH 13/90] working awesome --- .../pageSections/SearchSection/SearchResultsSlot.tsx | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/packages/visual-editor/src/components/pageSections/SearchSection/SearchResultsSlot.tsx b/packages/visual-editor/src/components/pageSections/SearchSection/SearchResultsSlot.tsx index 6d95e85819..01397de98c 100644 --- a/packages/visual-editor/src/components/pageSections/SearchSection/SearchResultsSlot.tsx +++ b/packages/visual-editor/src/components/pageSections/SearchSection/SearchResultsSlot.tsx @@ -95,10 +95,8 @@ const SearchResultsSlotInternal: PuckComponent = ( } searchActions.setUniversal(); - searchActions.setQuery(searchTerm); - searchActions.setRestrictVerticals( - verticals.filter((v) => v.verticalKey).map((v) => v.verticalKey as string) - ); + // searchActions.setQuery(searchTerm); + searchActions.setUniversalLimit(universalLimit); searchActions.executeUniversalQuery(); }, [verticals, searchTerm, universalLimit, searchActions]); From 96c80186d33567a3367f776c6c7bfca3962bcd6f Mon Sep 17 00:00:00 2001 From: rkeerthient Date: Wed, 11 Feb 2026 15:34:25 +0530 Subject: [PATCH 14/90] dynamic layout --- .../SearchSection/LayoutSections.tsx | 32 +++++++++++++++++++ .../SearchSection/SearchResultsSlot.tsx | 30 +++++++++++++++-- .../pageSections/SearchSection/utils.tsx | 9 ++++-- 3 files changed, 65 insertions(+), 6 deletions(-) create mode 100644 packages/visual-editor/src/components/pageSections/SearchSection/LayoutSections.tsx diff --git a/packages/visual-editor/src/components/pageSections/SearchSection/LayoutSections.tsx b/packages/visual-editor/src/components/pageSections/SearchSection/LayoutSections.tsx new file mode 100644 index 0000000000..d8f1e9293c --- /dev/null +++ b/packages/visual-editor/src/components/pageSections/SearchSection/LayoutSections.tsx @@ -0,0 +1,32 @@ +import { SectionProps, DefaultRawDataType } from "@yext/search-ui-react"; +import { VerticalLayout } from "./propsAndTypes.ts"; + +interface LayoutSectionProps extends SectionProps { + layoutType: VerticalLayout; +} + +export const LayoutSection = ({ + layoutType, + results, + CardComponent, + header, +}: LayoutSectionProps) => { + if (!CardComponent) return null; + const layoutClasses = + layoutType === "Grid" + ? "grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-6" + : "flex flex-col gap-4 w-full"; + return ( +
+

+ {header?.props.label.toUpperCase()} +

+ +
+ {results.map((result, index) => ( + + ))} +
+
+ ); +}; diff --git a/packages/visual-editor/src/components/pageSections/SearchSection/SearchResultsSlot.tsx b/packages/visual-editor/src/components/pageSections/SearchSection/SearchResultsSlot.tsx index 01397de98c..7ed356398d 100644 --- a/packages/visual-editor/src/components/pageSections/SearchSection/SearchResultsSlot.tsx +++ b/packages/visual-editor/src/components/pageSections/SearchSection/SearchResultsSlot.tsx @@ -1,4 +1,9 @@ -import { ComponentConfig, Fields, PuckComponent } from "@puckeditor/core"; +import { + ComponentConfig, + Fields, + PuckComponent, + // usePuck, +} from "@puckeditor/core"; import { useSearchActions, useSearchState } from "@yext/search-headless-react"; import { UniversalResults } from "@yext/search-ui-react"; import React from "react"; @@ -74,6 +79,27 @@ const SearchResultsSlotInternal: PuckComponent = ( const { data: { verticals }, } = props; + // const { appState } = usePuck(); + // const arrayState = appState.ui.arrayState; + + // const arrayKey = Object.keys(arrayState || {}).find((key) => + // key.includes("_object_data_verticals") + // ); + + // let selectedVerticalIndex: number | null = null; + + // if (arrayKey) { + // const verticalArrayState = arrayState[arrayKey]; + // const openId = verticalArrayState?.openId; + + // const selectedItem = verticalArrayState?.items?.find( + // (item) => item._arrayId === openId + // ); + + // selectedVerticalIndex = selectedItem?._currentIndex ?? null; + // } + + // console.log("Selected vertical index:", selectedVerticalIndex); const searchActions = useSearchActions(); const isLoading = useSearchState((s) => s.searchStatus.isLoading); @@ -95,8 +121,6 @@ const SearchResultsSlotInternal: PuckComponent = ( } searchActions.setUniversal(); - // searchActions.setQuery(searchTerm); - searchActions.setUniversalLimit(universalLimit); searchActions.executeUniversalQuery(); }, [verticals, searchTerm, universalLimit, searchActions]); diff --git a/packages/visual-editor/src/components/pageSections/SearchSection/utils.tsx b/packages/visual-editor/src/components/pageSections/SearchSection/utils.tsx index 28e986bf0a..9481d51f58 100644 --- a/packages/visual-editor/src/components/pageSections/SearchSection/utils.tsx +++ b/packages/visual-editor/src/components/pageSections/SearchSection/utils.tsx @@ -2,15 +2,16 @@ import { UniversalLimit } from "@yext/search-headless-react"; import { DefaultRawDataType, StandardCard, - StandardSection, VerticalConfigMap, } from "@yext/search-ui-react"; +import { LayoutSection } from "./LayoutSections.tsx"; +import { VerticalLayout } from "./propsAndTypes.ts"; export const buildVerticalConfigMap = ( verticals: { label: string; verticalKey?: string; - layout?: "Grid" | "Flex" | "Map"; + layout?: VerticalLayout; }[] ): VerticalConfigMap> => { return verticals.reduce( @@ -20,7 +21,9 @@ export const buildVerticalConfigMap = ( acc[v.verticalKey] = { label: v.label, viewAllButton: true, - SectionComponent: StandardSection, + SectionComponent: (props) => ( + + ), CardComponent: StandardCard, }; From 82ec15b9d9c2f562cf2d08433c74943d1a161931 Mon Sep 17 00:00:00 2001 From: rkeerthient Date: Wed, 11 Feb 2026 17:51:03 +0530 Subject: [PATCH 15/90] added hide vertical on home --- .../pageSections/SearchSection/Cards.tsx | 19 +++++++ .../pageSections/SearchSection/Search.tsx | 1 + .../SearchSection/SearchBarSlot.tsx | 6 +- .../SearchSection/SearchResultsSlot.tsx | 28 ++++++---- .../SearchSection/propsAndTypes.ts | 7 +++ .../pageSections/SearchSection/search.css | 3 + .../pageSections/SearchSection/utils.tsx | 55 ++++++++++++++++--- 7 files changed, 95 insertions(+), 24 deletions(-) create mode 100644 packages/visual-editor/src/components/pageSections/SearchSection/Cards.tsx create mode 100644 packages/visual-editor/src/components/pageSections/SearchSection/search.css diff --git a/packages/visual-editor/src/components/pageSections/SearchSection/Cards.tsx b/packages/visual-editor/src/components/pageSections/SearchSection/Cards.tsx new file mode 100644 index 0000000000..3ac5a1589c --- /dev/null +++ b/packages/visual-editor/src/components/pageSections/SearchSection/Cards.tsx @@ -0,0 +1,19 @@ +import { CardProps, DefaultRawDataType } from "@yext/search-ui-react"; +import { CardTypeProp } from "./propsAndTypes.ts"; + +interface CardsProps extends CardProps { + cardType?: CardTypeProp; +} + +const Cards = ({ result, cardType = "Standard" }: CardsProps) => { + const name = + typeof result.rawData?.name === "string" ? result.rawData.name : ""; + + return ( +
+ {cardType} — {name} +
+ ); +}; + +export default Cards; diff --git a/packages/visual-editor/src/components/pageSections/SearchSection/Search.tsx b/packages/visual-editor/src/components/pageSections/SearchSection/Search.tsx index 41a0efcc1e..f44c398e8c 100644 --- a/packages/visual-editor/src/components/pageSections/SearchSection/Search.tsx +++ b/packages/visual-editor/src/components/pageSections/SearchSection/Search.tsx @@ -13,6 +13,7 @@ import { msg } from "../../../utils/index.ts"; import { PageSection } from "../../atoms/pageSection.tsx"; import { SearchBarSlotProps } from "./SearchBarSlot.tsx"; import { SearchResultsSlotProps } from "./SearchResultsSlot.tsx"; +import "./search.css"; export interface SearchComponentProps { /** @internal */ diff --git a/packages/visual-editor/src/components/pageSections/SearchSection/SearchBarSlot.tsx b/packages/visual-editor/src/components/pageSections/SearchSection/SearchBarSlot.tsx index f9ce445f1c..4962ce4dc4 100644 --- a/packages/visual-editor/src/components/pageSections/SearchSection/SearchBarSlot.tsx +++ b/packages/visual-editor/src/components/pageSections/SearchSection/SearchBarSlot.tsx @@ -27,11 +27,7 @@ const searchBarSlotFields: Fields = { }; const SearchBarSlotInternal: PuckComponent = (props) => { - const { - styles: { showIcon = false }, - puck, - } = props; - console.log(showIcon); + const { puck } = props; if (puck.isEditing) { return (
diff --git a/packages/visual-editor/src/components/pageSections/SearchSection/SearchResultsSlot.tsx b/packages/visual-editor/src/components/pageSections/SearchSection/SearchResultsSlot.tsx index 7ed356398d..809ed6249a 100644 --- a/packages/visual-editor/src/components/pageSections/SearchSection/SearchResultsSlot.tsx +++ b/packages/visual-editor/src/components/pageSections/SearchSection/SearchResultsSlot.tsx @@ -16,10 +16,12 @@ import { buildVerticalConfigMap, isValidVerticalConfig, } from "./utils.tsx"; + export interface SearchResultsSlotProps { data: { verticals: VerticalConfig[] }; styles: { showIcon: boolean }; } + const SearchResultsSlotFields: Fields = { data: YextField(msg("fields.data", "Data"), { type: "object", @@ -29,11 +31,9 @@ const SearchResultsSlotFields: Fields = { type: "array", arrayFields: { label: YextField(msg("fields.label", "Label"), { type: "text" }), - verticalKey: YextField(msg("fields.verticalKey", "Vertical Key"), { type: "text", }), - layout: YextField(msg("fields.layout", "Layout"), { type: "radio", options: [ @@ -42,12 +42,17 @@ const SearchResultsSlotFields: Fields = { { label: "Map", value: "Map" }, ], }), - + cardType: YextField(msg("fields.layout", "Layout"), { + type: "radio", + options: [ + { label: "Standard", value: "standard" }, + { label: "Accordion", value: "accordion" }, + ], + }), universalLimit: YextField( msg("fields.universalLimit", "Universal Limit"), { type: "number" } ), - verticalLimit: YextField( msg("fields.verticalLimit", "Vertical Limit"), { @@ -118,11 +123,11 @@ const SearchResultsSlotInternal: PuckComponent = ( if (!isValidVerticalConfig(verticals)) { console.warn("Skipping search: invalid vertical config", verticals); return; + } else { + searchActions.setUniversal(); + searchActions.setUniversalLimit(universalLimit); + searchActions.executeUniversalQuery(); } - - searchActions.setUniversal(); - searchActions.setUniversalLimit(universalLimit); - searchActions.executeUniversalQuery(); }, [verticals, searchTerm, universalLimit, searchActions]); return ( @@ -131,7 +136,10 @@ const SearchResultsSlotInternal: PuckComponent = (
- + {isLoading &&
Loading......
} {!isLoading && ( > => { return verticals.reduce( (acc, v) => { if (!v.verticalKey) return acc; - + const layoutType = v.layout ?? "Grid"; + const cardType = v.cardType ?? "Standard"; acc[v.verticalKey] = { label: v.label, viewAllButton: true, SectionComponent: (props) => ( - + ), - CardComponent: StandardCard, + CardComponent: (props) => , }; return acc; @@ -71,3 +70,41 @@ export const isValidVerticalConfig = (verticals: any[]): boolean => { verticals.every(isValidVertical) ); }; + +// export const buildVerticalConfigMap = ( +// verticals: { +// label: string; +// verticalKey?: string; +// layout?: VerticalLayout; +// cardType?: CardTypeProp; +// }[] +// ): VerticalConfigMap> => { +// return verticals.reduce( +// (acc, v) => { +// if (!v.verticalKey) return acc; + +// const layoutType = v.layout ?? "Grid"; +// const cardType = v.cardType ?? "Standard"; + +// // Stable Section component per vertical +// const SectionComponent: React.FC> = ( +// props +// ) => ; + +// // Stable Card component per vertical +// const CardComponent: React.FC> = ( +// props +// ) => ; + +// acc[v.verticalKey] = { +// label: v.label, +// viewAllButton: true, +// SectionComponent, +// CardComponent, +// }; + +// return acc; +// }, +// {} as VerticalConfigMap> +// ); +// }; From fdc722e5ae5dfe01d89541c7a9d35e826acbb7d3 Mon Sep 17 00:00:00 2001 From: rkeerthient Date: Wed, 11 Feb 2026 18:13:05 +0530 Subject: [PATCH 16/90] added native styling --- .../pageSections/SearchSection/Cards.tsx | 16 ++++++++++++---- 1 file changed, 12 insertions(+), 4 deletions(-) diff --git a/packages/visual-editor/src/components/pageSections/SearchSection/Cards.tsx b/packages/visual-editor/src/components/pageSections/SearchSection/Cards.tsx index 3ac5a1589c..7875c99ec8 100644 --- a/packages/visual-editor/src/components/pageSections/SearchSection/Cards.tsx +++ b/packages/visual-editor/src/components/pageSections/SearchSection/Cards.tsx @@ -1,17 +1,25 @@ import { CardProps, DefaultRawDataType } from "@yext/search-ui-react"; import { CardTypeProp } from "./propsAndTypes.ts"; +import { Heading } from "../../atoms/heading.tsx"; +import { Body } from "../../atoms/body.tsx"; interface CardsProps extends CardProps { cardType?: CardTypeProp; } const Cards = ({ result, cardType = "Standard" }: CardsProps) => { - const name = - typeof result.rawData?.name === "string" ? result.rawData.name : ""; + // const name = + // typeof result.rawData?.name === "string" ? result.rawData.name : ""; return ( -
- {cardType} — {name} +
+
+
+
+ {(result.rawData?.name as any) ?? "name"} + {cardType} +
+
); }; From fb48567f5cf29ceee90e12edc1b027efd6bcda25 Mon Sep 17 00:00:00 2001 From: rkeerthient Date: Wed, 11 Feb 2026 23:13:14 +0530 Subject: [PATCH 17/90] nit updates --- .../SearchSection/GridSection.tsx | 19 ------------------ .../SearchSection/LayoutSections.tsx | 6 ++++++ .../SearchSection/SearchResultsSlot.tsx | 7 +++++-- .../SearchSection/propsAndTypes.ts | 2 +- .../pageSections/SearchSection/utils.tsx | 20 +++++++++---------- 5 files changed, 21 insertions(+), 33 deletions(-) delete mode 100644 packages/visual-editor/src/components/pageSections/SearchSection/GridSection.tsx diff --git a/packages/visual-editor/src/components/pageSections/SearchSection/GridSection.tsx b/packages/visual-editor/src/components/pageSections/SearchSection/GridSection.tsx deleted file mode 100644 index e18c9fa3c1..0000000000 --- a/packages/visual-editor/src/components/pageSections/SearchSection/GridSection.tsx +++ /dev/null @@ -1,19 +0,0 @@ -import React from "react"; -import { DefaultRawDataType, SectionProps } from "@yext/search-ui-react"; - -export const GridSection = ({ - results, - CardComponent, -}: SectionProps) => { - if (!results || !results.length || !CardComponent) { - return null; - } - - return ( -
- {results.map((result, index) => ( - - ))} -
- ); -}; diff --git a/packages/visual-editor/src/components/pageSections/SearchSection/LayoutSections.tsx b/packages/visual-editor/src/components/pageSections/SearchSection/LayoutSections.tsx index d8f1e9293c..3f48fa862f 100644 --- a/packages/visual-editor/src/components/pageSections/SearchSection/LayoutSections.tsx +++ b/packages/visual-editor/src/components/pageSections/SearchSection/LayoutSections.tsx @@ -3,6 +3,7 @@ import { VerticalLayout } from "./propsAndTypes.ts"; interface LayoutSectionProps extends SectionProps { layoutType: VerticalLayout; + resultsCount: number; } export const LayoutSection = ({ @@ -10,12 +11,17 @@ export const LayoutSection = ({ results, CardComponent, header, + resultsCount = 4, }: LayoutSectionProps) => { if (!CardComponent) return null; const layoutClasses = layoutType === "Grid" ? "grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-6" : "flex flex-col gap-4 w-full"; + console.log(resultsCount); + + // const filteredResults = results.slice(0, resultsCount); + return (

diff --git a/packages/visual-editor/src/components/pageSections/SearchSection/SearchResultsSlot.tsx b/packages/visual-editor/src/components/pageSections/SearchSection/SearchResultsSlot.tsx index 809ed6249a..6f40733437 100644 --- a/packages/visual-editor/src/components/pageSections/SearchSection/SearchResultsSlot.tsx +++ b/packages/visual-editor/src/components/pageSections/SearchSection/SearchResultsSlot.tsx @@ -10,7 +10,10 @@ import React from "react"; import { FaEllipsisV } from "react-icons/fa"; import { YextField } from "../../../editor/YextField.tsx"; import { msg } from "../../../utils/index.ts"; -import { defaultSearchResultsProps, VerticalConfig } from "./propsAndTypes.ts"; +import { + defaultSearchResultsProps, + VerticalConfigProps, +} from "./propsAndTypes.ts"; import { buildUniversalLimit, buildVerticalConfigMap, @@ -18,7 +21,7 @@ import { } from "./utils.tsx"; export interface SearchResultsSlotProps { - data: { verticals: VerticalConfig[] }; + data: { verticals: VerticalConfigProps[] }; styles: { showIcon: boolean }; } diff --git a/packages/visual-editor/src/components/pageSections/SearchSection/propsAndTypes.ts b/packages/visual-editor/src/components/pageSections/SearchSection/propsAndTypes.ts index 018c70f47d..da277b5d00 100644 --- a/packages/visual-editor/src/components/pageSections/SearchSection/propsAndTypes.ts +++ b/packages/visual-editor/src/components/pageSections/SearchSection/propsAndTypes.ts @@ -3,7 +3,7 @@ import { SearchResultsSlotProps } from "./SearchResultsSlot.tsx"; export type VerticalLayout = "Grid" | "Flex" | "Map"; export type CardTypeProp = "Standard" | "accordion"; -export interface VerticalConfig { +export interface VerticalConfigProps { label: string; verticalKey?: string; layout?: VerticalLayout; diff --git a/packages/visual-editor/src/components/pageSections/SearchSection/utils.tsx b/packages/visual-editor/src/components/pageSections/SearchSection/utils.tsx index e632b08e4a..bfd050872b 100644 --- a/packages/visual-editor/src/components/pageSections/SearchSection/utils.tsx +++ b/packages/visual-editor/src/components/pageSections/SearchSection/utils.tsx @@ -1,16 +1,11 @@ import { UniversalLimit } from "@yext/search-headless-react"; -import { VerticalConfigMap, DefaultRawDataType } from "@yext/search-ui-react"; +import { DefaultRawDataType, VerticalConfigMap } from "@yext/search-ui-react"; import Cards from "./Cards.tsx"; import { LayoutSection } from "./LayoutSections.tsx"; -import { VerticalLayout, CardTypeProp } from "./propsAndTypes.ts"; +import { VerticalConfigProps } from "./propsAndTypes.ts"; export const buildVerticalConfigMap = ( - verticals: { - label: string; - verticalKey?: string; - layout?: VerticalLayout; - cardType?: CardTypeProp; - }[] + verticals: VerticalConfigProps[] ): VerticalConfigMap> => { return verticals.reduce( (acc, v) => { @@ -21,11 +16,14 @@ export const buildVerticalConfigMap = ( label: v.label, viewAllButton: true, SectionComponent: (props) => ( - + ), CardComponent: (props) => , }; - return acc; }, {} as VerticalConfigMap> @@ -43,8 +41,8 @@ export const buildUniversalLimit = ( if (!v.verticalKey || typeof v.universalLimit !== "number") { return acc; } - acc[v.verticalKey] = v.universalLimit; + // acc[v.verticalKey] = 50; return acc; }, {}); }; From 59c9141a8b4a40f0b41a0a9e169fbbb467b27942 Mon Sep 17 00:00:00 2001 From: rkeerthient Date: Thu, 12 Feb 2026 00:33:38 +0530 Subject: [PATCH 18/90] vertical limit and additional verticals added --- .../pageSections/SearchSection/Search.tsx | 9 +-- .../SearchSection/SearchResultsSlot.tsx | 65 +++++++++++-------- .../SearchSection/propsAndTypes.ts | 18 ----- .../pageSections/SearchSection/utils.tsx | 38 ----------- 4 files changed, 41 insertions(+), 89 deletions(-) diff --git a/packages/visual-editor/src/components/pageSections/SearchSection/Search.tsx b/packages/visual-editor/src/components/pageSections/SearchSection/Search.tsx index f44c398e8c..da8ddb4112 100644 --- a/packages/visual-editor/src/components/pageSections/SearchSection/Search.tsx +++ b/packages/visual-editor/src/components/pageSections/SearchSection/Search.tsx @@ -14,6 +14,7 @@ import { PageSection } from "../../atoms/pageSection.tsx"; import { SearchBarSlotProps } from "./SearchBarSlot.tsx"; import { SearchResultsSlotProps } from "./SearchResultsSlot.tsx"; import "./search.css"; +import { defaultSearchResultsProps } from "./propsAndTypes.ts"; export interface SearchComponentProps { /** @internal */ @@ -107,13 +108,7 @@ export const SearchComponent: ComponentConfig<{ label: "All", pageType: "universal", }, - { - label: "FAQs", - verticalKey: "faq", - layout: "Flex", - universalLimit: 3, - verticalLimit: 5, - }, + defaultSearchResultsProps.data.verticals[0], ], }, styles: { diff --git a/packages/visual-editor/src/components/pageSections/SearchSection/SearchResultsSlot.tsx b/packages/visual-editor/src/components/pageSections/SearchSection/SearchResultsSlot.tsx index 6f40733437..0f3c2cd3c0 100644 --- a/packages/visual-editor/src/components/pageSections/SearchSection/SearchResultsSlot.tsx +++ b/packages/visual-editor/src/components/pageSections/SearchSection/SearchResultsSlot.tsx @@ -1,12 +1,11 @@ -import { - ComponentConfig, - Fields, - PuckComponent, - // usePuck, -} from "@puckeditor/core"; +import { ComponentConfig, Fields, PuckComponent } from "@puckeditor/core"; import { useSearchActions, useSearchState } from "@yext/search-headless-react"; -import { UniversalResults } from "@yext/search-ui-react"; -import React from "react"; +import { + StandardCard, + UniversalResults, + VerticalResults, +} from "@yext/search-ui-react"; +import React, { useState } from "react"; import { FaEllipsisV } from "react-icons/fa"; import { YextField } from "../../../editor/YextField.tsx"; import { msg } from "../../../utils/index.ts"; @@ -45,11 +44,11 @@ const SearchResultsSlotFields: Fields = { { label: "Map", value: "Map" }, ], }), - cardType: YextField(msg("fields.layout", "Layout"), { + cardType: YextField(msg("fields.cardType", "Card Type"), { type: "radio", options: [ - { label: "Standard", value: "standard" }, - { label: "Accordion", value: "accordion" }, + { label: "Standard", value: "Standard" }, + { label: "Accordion", value: "Accordion" }, ], }), universalLimit: YextField( @@ -112,6 +111,8 @@ const SearchResultsSlotInternal: PuckComponent = ( const searchActions = useSearchActions(); const isLoading = useSearchState((s) => s.searchStatus.isLoading); const searchTerm = useSearchState((s) => s.query.input) ?? " "; + const [verticalKey, setVerticalKey] = useState(); + const verticalConfigMap = React.useMemo( () => buildVerticalConfigMap(verticals), [verticals] @@ -127,11 +128,20 @@ const SearchResultsSlotInternal: PuckComponent = ( console.warn("Skipping search: invalid vertical config", verticals); return; } else { - searchActions.setUniversal(); - searchActions.setUniversalLimit(universalLimit); - searchActions.executeUniversalQuery(); + if (verticalKey) { + const verticalLimit = verticals.find( + (item) => item.verticalKey === verticalKey + )?.verticalLimit; + searchActions.setVertical(verticalKey); + searchActions.setVerticalLimit(verticalLimit!); + searchActions.executeVerticalQuery(); + } else { + searchActions.setUniversal(); + searchActions.setUniversalLimit(universalLimit); + searchActions.executeUniversalQuery(); + } } - }, [verticals, searchTerm, universalLimit, searchActions]); + }, [verticals, searchTerm, universalLimit, searchActions, verticalKey]); return (
@@ -140,8 +150,8 @@ const SearchResultsSlotInternal: PuckComponent = ( {verticals.map((item) => (
  • console.log("clicked")} - className="px-5 pt-1.5 pb-1 tracking-[1.1px] mb-0" + onClick={() => setVerticalKey(item.verticalKey)} + className="px-5 pt-1.5 pb-1 tracking-[1.1px] mb-0 hover:cursor-pointer" > {item.label} @@ -156,15 +166,18 @@ const SearchResultsSlotInternal: PuckComponent = (
  • {isLoading &&
    Loading......
    } - {!isLoading && ( - - )} + {!isLoading && + (verticalKey ? ( + + ) : ( + + ))}
    ); }; diff --git a/packages/visual-editor/src/components/pageSections/SearchSection/propsAndTypes.ts b/packages/visual-editor/src/components/pageSections/SearchSection/propsAndTypes.ts index da277b5d00..42ac7e1153 100644 --- a/packages/visual-editor/src/components/pageSections/SearchSection/propsAndTypes.ts +++ b/packages/visual-editor/src/components/pageSections/SearchSection/propsAndTypes.ts @@ -24,24 +24,6 @@ export const defaultSearchResultsProps: SearchResultsSlotProps = { universalLimit: 3, verticalLimit: 5, }, - { - label: "Products", - verticalKey: "product", - layout: "Grid", - cardType: "Standard", - - universalLimit: 3, - verticalLimit: 5, - }, - { - label: "Locations", - verticalKey: "locations", - layout: "Map", - cardType: "Standard", - - universalLimit: 3, - verticalLimit: 5, - }, ], }, styles: { diff --git a/packages/visual-editor/src/components/pageSections/SearchSection/utils.tsx b/packages/visual-editor/src/components/pageSections/SearchSection/utils.tsx index bfd050872b..3811d2eb45 100644 --- a/packages/visual-editor/src/components/pageSections/SearchSection/utils.tsx +++ b/packages/visual-editor/src/components/pageSections/SearchSection/utils.tsx @@ -68,41 +68,3 @@ export const isValidVerticalConfig = (verticals: any[]): boolean => { verticals.every(isValidVertical) ); }; - -// export const buildVerticalConfigMap = ( -// verticals: { -// label: string; -// verticalKey?: string; -// layout?: VerticalLayout; -// cardType?: CardTypeProp; -// }[] -// ): VerticalConfigMap> => { -// return verticals.reduce( -// (acc, v) => { -// if (!v.verticalKey) return acc; - -// const layoutType = v.layout ?? "Grid"; -// const cardType = v.cardType ?? "Standard"; - -// // Stable Section component per vertical -// const SectionComponent: React.FC> = ( -// props -// ) => ; - -// // Stable Card component per vertical -// const CardComponent: React.FC> = ( -// props -// ) => ; - -// acc[v.verticalKey] = { -// label: v.label, -// viewAllButton: true, -// SectionComponent, -// CardComponent, -// }; - -// return acc; -// }, -// {} as VerticalConfigMap> -// ); -// }; From 53206c5cb0b54a4f45216396981572b6c172c274 Mon Sep 17 00:00:00 2001 From: rkeerthient Date: Thu, 12 Feb 2026 02:06:48 +0530 Subject: [PATCH 19/90] awesome development --- .../pageSections/SearchSection/Cards.tsx | 44 +++++++++++++++---- .../SearchSection/LayoutSections.tsx | 13 +++--- 2 files changed, 42 insertions(+), 15 deletions(-) diff --git a/packages/visual-editor/src/components/pageSections/SearchSection/Cards.tsx b/packages/visual-editor/src/components/pageSections/SearchSection/Cards.tsx index 7875c99ec8..e7d6bfa79d 100644 --- a/packages/visual-editor/src/components/pageSections/SearchSection/Cards.tsx +++ b/packages/visual-editor/src/components/pageSections/SearchSection/Cards.tsx @@ -1,7 +1,5 @@ import { CardProps, DefaultRawDataType } from "@yext/search-ui-react"; import { CardTypeProp } from "./propsAndTypes.ts"; -import { Heading } from "../../atoms/heading.tsx"; -import { Body } from "../../atoms/body.tsx"; interface CardsProps extends CardProps { cardType?: CardTypeProp; @@ -12,12 +10,42 @@ const Cards = ({ result, cardType = "Standard" }: CardsProps) => { // typeof result.rawData?.name === "string" ? result.rawData.name : ""; return ( -
    -
    -
    -
    - {(result.rawData?.name as any) ?? "name"} - {cardType} +
    +
    +

    + {(result.rawData?.name as any) ?? "name"} +

    +
    +

    + Lorem ipsum dolor sit amet consectetur, adipisicing elit. Impedit + illo tenetur aut quas, dolor repudiandae dignissimos cumque + asperiores doloribus blanditiis molestiae omnis quo. Consequatur + accusamus distinctio sint alias dignissimos labore! Lorem ipsum + dolor sit amet consectetur, adipisicing elit. Impedit illo tenetur + aut quas, dolor repudiandae dignissimos cumque asperiores doloribus + blanditiis molestiae omnis quo. Consequatur accusamus distinctio + sint alias dignissimos labore! Lorem ipsum dolor sit amet + consectetur, adipisicing elit. Impedit illo tenetur aut quas, dolor + repudiandae dignissimos cumque asperiores doloribus blanditiis + molestiae omnis quo. Consequatur accusamus distinctio sint alias + dignissimos labore! Lorem ipsum dolor sit amet consectetur, + adipisicing elit. Impedit illo tenetur aut quas, dolor repudiandae + dignissimos cumque asperiores doloribus blanditiis molestiae omnis + quo. Consequatur accusamus distinctio sint alias dignissimos labore! + Lorem ipsum dolor sit amet consectetur, adipisicing elit. Impedit + illo tenetur aut quas, dolor repudiandae dignissimos cumque + asperiores doloribus blanditiis molestiae omnis quo. Consequatur + accusamus distinctio sint alias dignissimos labore! Lorem ipsum + dolor sit amet consectetur, adipisicing elit. Impedit illo tenetur + aut quas, dolor repudiandae dignissimos cumque asperiores doloribus + blanditiis molestiae omnis quo. Consequatur accusamus distinctio + sint alias dignissimos labore! +

    +
    diff --git a/packages/visual-editor/src/components/pageSections/SearchSection/LayoutSections.tsx b/packages/visual-editor/src/components/pageSections/SearchSection/LayoutSections.tsx index 3f48fa862f..e7a1b72035 100644 --- a/packages/visual-editor/src/components/pageSections/SearchSection/LayoutSections.tsx +++ b/packages/visual-editor/src/components/pageSections/SearchSection/LayoutSections.tsx @@ -17,18 +17,17 @@ export const LayoutSection = ({ const layoutClasses = layoutType === "Grid" ? "grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-6" - : "flex flex-col gap-4 w-full"; + : "flex flex-col w-full"; console.log(resultsCount); // const filteredResults = results.slice(0, resultsCount); return ( -
    -

    - {header?.props.label.toUpperCase()} -

    - -
    +
    +
    +

    {header?.props.label}

    +
    +
    {results.map((result, index) => ( ))} From 65c9b29326228fb3d08ee903ecbf9f1e926cacc3 Mon Sep 17 00:00:00 2001 From: rkeerthient Date: Thu, 12 Feb 2026 16:45:13 +0530 Subject: [PATCH 20/90] updated card forms --- .../pageSections/SearchSection/Cards.tsx | 99 +++++++++++-------- .../SearchSection/LayoutSections.tsx | 4 +- .../pageSections/SearchSection/Search.tsx | 9 +- .../SearchSection/SearchResultsSlot.tsx | 28 ++++-- 4 files changed, 88 insertions(+), 52 deletions(-) diff --git a/packages/visual-editor/src/components/pageSections/SearchSection/Cards.tsx b/packages/visual-editor/src/components/pageSections/SearchSection/Cards.tsx index e7d6bfa79d..c1beeb1c81 100644 --- a/packages/visual-editor/src/components/pageSections/SearchSection/Cards.tsx +++ b/packages/visual-editor/src/components/pageSections/SearchSection/Cards.tsx @@ -1,55 +1,76 @@ -import { CardProps, DefaultRawDataType } from "@yext/search-ui-react"; +import { CardProps } from "@yext/search-ui-react"; +import { MaybeRTF } from "@yext/visual-editor"; +import { + Accordion, + AccordionContent, + AccordionItem, + AccordionTrigger, +} from "../../atoms/accordion.tsx"; import { CardTypeProp } from "./propsAndTypes.ts"; -interface CardsProps extends CardProps { +interface CardsProps extends CardProps { cardType?: CardTypeProp; } const Cards = ({ result, cardType = "Standard" }: CardsProps) => { // const name = // typeof result.rawData?.name === "string" ? result.rawData.name : ""; - return ( -
    -
    -

    - {(result.rawData?.name as any) ?? "name"} -

    -
    -

    - Lorem ipsum dolor sit amet consectetur, adipisicing elit. Impedit - illo tenetur aut quas, dolor repudiandae dignissimos cumque - asperiores doloribus blanditiis molestiae omnis quo. Consequatur - accusamus distinctio sint alias dignissimos labore! Lorem ipsum - dolor sit amet consectetur, adipisicing elit. Impedit illo tenetur - aut quas, dolor repudiandae dignissimos cumque asperiores doloribus - blanditiis molestiae omnis quo. Consequatur accusamus distinctio - sint alias dignissimos labore! Lorem ipsum dolor sit amet - consectetur, adipisicing elit. Impedit illo tenetur aut quas, dolor - repudiandae dignissimos cumque asperiores doloribus blanditiis - molestiae omnis quo. Consequatur accusamus distinctio sint alias - dignissimos labore! Lorem ipsum dolor sit amet consectetur, - adipisicing elit. Impedit illo tenetur aut quas, dolor repudiandae - dignissimos cumque asperiores doloribus blanditiis molestiae omnis - quo. Consequatur accusamus distinctio sint alias dignissimos labore! - Lorem ipsum dolor sit amet consectetur, adipisicing elit. Impedit - illo tenetur aut quas, dolor repudiandae dignissimos cumque - asperiores doloribus blanditiis molestiae omnis quo. Consequatur - accusamus distinctio sint alias dignissimos labore! Lorem ipsum - dolor sit amet consectetur, adipisicing elit. Impedit illo tenetur - aut quas, dolor repudiandae dignissimos cumque asperiores doloribus - blanditiis molestiae omnis quo. Consequatur accusamus distinctio - sint alias dignissimos labore! -

    -
    - - {cardType} - +
    + {cardType === "Standard" ? ( +
    +

    + {(result.rawData?.name as any) ?? "name"} +

    +
    -
    + ) : ( + + + +

    + {(result.rawData?.name as any) ?? "name"} +

    +
    + + + +
    +
    + )}
    ); }; export default Cards; + +// const isJsonRT = (data: any) => { +// ; +// }; diff --git a/packages/visual-editor/src/components/pageSections/SearchSection/LayoutSections.tsx b/packages/visual-editor/src/components/pageSections/SearchSection/LayoutSections.tsx index e7a1b72035..6dbf266596 100644 --- a/packages/visual-editor/src/components/pageSections/SearchSection/LayoutSections.tsx +++ b/packages/visual-editor/src/components/pageSections/SearchSection/LayoutSections.tsx @@ -14,10 +14,12 @@ export const LayoutSection = ({ resultsCount = 4, }: LayoutSectionProps) => { if (!CardComponent) return null; + const layoutClasses = layoutType === "Grid" ? "grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-6" : "flex flex-col w-full"; + console.log(resultsCount); // const filteredResults = results.slice(0, resultsCount); @@ -25,7 +27,7 @@ export const LayoutSection = ({ return (
    -

    {header?.props.label}

    +

    {header?.props.label}

    {results.map((result, index) => ( diff --git a/packages/visual-editor/src/components/pageSections/SearchSection/Search.tsx b/packages/visual-editor/src/components/pageSections/SearchSection/Search.tsx index da8ddb4112..884092eef1 100644 --- a/packages/visual-editor/src/components/pageSections/SearchSection/Search.tsx +++ b/packages/visual-editor/src/components/pageSections/SearchSection/Search.tsx @@ -8,13 +8,14 @@ import { } from "@yext/search-headless-react"; import { SearchI18nextProvider } from "@yext/search-ui-react"; import React from "react"; -import { useDocument } from "../../../hooks/useDocument.tsx"; -import { msg } from "../../../utils/index.ts"; -import { PageSection } from "../../atoms/pageSection.tsx"; import { SearchBarSlotProps } from "./SearchBarSlot.tsx"; import { SearchResultsSlotProps } from "./SearchResultsSlot.tsx"; +//@ts-ignore import "./search.css"; import { defaultSearchResultsProps } from "./propsAndTypes.ts"; +import { useDocument } from "../../../hooks/useDocument.tsx"; +import { PageSection } from "../../atoms/pageSection.tsx"; +import { msg } from "../../../utils/index.ts"; export interface SearchComponentProps { /** @internal */ @@ -37,7 +38,7 @@ const EXPERIENCE_VERSION = "PRODUCTION"; export const searchConfig: SearchConfig = { apiKey: "fb73f1bf6a262bc3255bcb938088204f", - experienceKey: "ukg-fins", + experienceKey: "ukg-fins-rk-test-dont-touch", locale: "en", experienceVersion: EXPERIENCE_VERSION, cloudRegion: CloudRegion.US, diff --git a/packages/visual-editor/src/components/pageSections/SearchSection/SearchResultsSlot.tsx b/packages/visual-editor/src/components/pageSections/SearchSection/SearchResultsSlot.tsx index 0f3c2cd3c0..f7f8ae1a54 100644 --- a/packages/visual-editor/src/components/pageSections/SearchSection/SearchResultsSlot.tsx +++ b/packages/visual-editor/src/components/pageSections/SearchSection/SearchResultsSlot.tsx @@ -1,14 +1,9 @@ import { ComponentConfig, Fields, PuckComponent } from "@puckeditor/core"; import { useSearchActions, useSearchState } from "@yext/search-headless-react"; -import { - StandardCard, - UniversalResults, - VerticalResults, -} from "@yext/search-ui-react"; +import { UniversalResults, VerticalResults } from "@yext/search-ui-react"; import React, { useState } from "react"; import { FaEllipsisV } from "react-icons/fa"; -import { YextField } from "../../../editor/YextField.tsx"; -import { msg } from "../../../utils/index.ts"; +import Cards from "./Cards.tsx"; import { defaultSearchResultsProps, VerticalConfigProps, @@ -18,6 +13,8 @@ import { buildVerticalConfigMap, isValidVerticalConfig, } from "./utils.tsx"; +import { YextField } from "../../../editor/YextField.tsx"; +import { msg } from "../../../utils/index.ts"; export interface SearchResultsSlotProps { data: { verticals: VerticalConfigProps[] }; @@ -137,6 +134,7 @@ const SearchResultsSlotInternal: PuckComponent = ( searchActions.executeVerticalQuery(); } else { searchActions.setUniversal(); + // searchActions.setQuery("faq"); searchActions.setUniversalLimit(universalLimit); searchActions.executeUniversalQuery(); } @@ -168,7 +166,21 @@ const SearchResultsSlotInternal: PuckComponent = ( {isLoading &&
    Loading......
    } {!isLoading && (verticalKey ? ( - + ( + item.verticalKey === verticalKey) + ?.cardType + } + /> + )} + // CardComponent={ + // verticals.find((item) => item.verticalKey === verticalKey) + // ?.cardType + // } + /> ) : ( Date: Fri, 13 Feb 2026 18:47:01 +0530 Subject: [PATCH 21/90] added props to searchbar --- .../pageSections/SearchSection/Search.tsx | 1 + .../SearchSection/SearchBarSlot.tsx | 49 ++++++++++++++----- .../SearchSection/SearchResultsSlot.tsx | 2 +- 3 files changed, 38 insertions(+), 14 deletions(-) diff --git a/packages/visual-editor/src/components/pageSections/SearchSection/Search.tsx b/packages/visual-editor/src/components/pageSections/SearchSection/Search.tsx index 884092eef1..6486f6ff15 100644 --- a/packages/visual-editor/src/components/pageSections/SearchSection/Search.tsx +++ b/packages/visual-editor/src/components/pageSections/SearchSection/Search.tsx @@ -95,6 +95,7 @@ export const SearchComponent: ComponentConfig<{ props: { styles: { showIcon: false, + voiceSearch: false, }, } satisfies SearchBarSlotProps, }, diff --git a/packages/visual-editor/src/components/pageSections/SearchSection/SearchBarSlot.tsx b/packages/visual-editor/src/components/pageSections/SearchSection/SearchBarSlot.tsx index 4962ce4dc4..de2d8d95a3 100644 --- a/packages/visual-editor/src/components/pageSections/SearchSection/SearchBarSlot.tsx +++ b/packages/visual-editor/src/components/pageSections/SearchSection/SearchBarSlot.tsx @@ -1,18 +1,21 @@ import { ComponentConfig, Fields, PuckComponent } from "@puckeditor/core"; import { YextField } from "../../../editor/YextField.tsx"; import { msg } from "../../../utils/index.ts"; +import { SearchBar } from "@yext/search-ui-react"; +import { FaMicrophone } from "react-icons/fa"; export interface SearchBarSlotProps { - styles: { showIcon: boolean }; + styles: { showIcon: boolean; voiceSearch: boolean }; } const defaultSearchBarProps: SearchBarSlotProps = { styles: { showIcon: false, + voiceSearch: false, }, }; const searchBarSlotFields: Fields = { - styles: YextField(msg("fields.styles", "Styles"), { + styles: { type: "object", objectFields: { showIcon: YextField(msg("fields.showIcon", "Show Icon"), { @@ -22,20 +25,40 @@ const searchBarSlotFields: Fields = { { label: msg("fields.options.hide", "Hide"), value: false }, ], }), + voiceSearch: YextField(msg("fields.voiceSearch", "Voice Search"), { + type: "radio", + options: [ + { label: msg("fields.options.show", "Show"), value: true }, + { label: msg("fields.options.hide", "Hide"), value: false }, + ], + }), }, - }), + }, }; -const SearchBarSlotInternal: PuckComponent = (props) => { - const { puck } = props; - if (puck.isEditing) { - return ( -
    - Search Bar -
    - ); - } - return
    Search Slot
    ; +const SearchBarSlotInternal: PuckComponent = ({ + styles: { showIcon = false, voiceSearch = false }, +}: SearchBarSlotProps) => { + console.log(showIcon); + + return ( +
    + div]:border [&>div]:border-[#137350] [&>div]:rounded-md !mb-0 relative", + searchButtonContainer: voiceSearch ? "ml-14 my-auto" : "", + searchButton: "h-8 w-8 ", + inputElement: + "text-lg h-14 outline-none focus:outline-none focus:ring-0 focus:border-none px-5 py-2.5", + }} + /> + {voiceSearch && ( + + )} +
    + ); }; export const SearchBarSlot: ComponentConfig<{ props: SearchBarSlotProps }> = { diff --git a/packages/visual-editor/src/components/pageSections/SearchSection/SearchResultsSlot.tsx b/packages/visual-editor/src/components/pageSections/SearchSection/SearchResultsSlot.tsx index f7f8ae1a54..809fb29954 100644 --- a/packages/visual-editor/src/components/pageSections/SearchSection/SearchResultsSlot.tsx +++ b/packages/visual-editor/src/components/pageSections/SearchSection/SearchResultsSlot.tsx @@ -142,7 +142,7 @@ const SearchResultsSlotInternal: PuckComponent = ( }, [verticals, searchTerm, universalLimit, searchActions, verticalKey]); return ( -
    +