npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@salesforce/ui-bundle-template-feature-react-global-search

v1.119.6

Published

Global search feature for Salesforce objects with filtering and pagination

Downloads

1,412

Readme

Feature: React Global Search (Single Object)

This package is a reference implementation for adding global search (keyword search, filters, results list, and record detail) to a Salesforce UI Bundle. It provides API services, hooks, types/schemas, and utilities so you can build your own UI and import the data layer from the package—or optionally copy the reference UI from the package and adapt it.

Intended use (vibing model):

  • Do not copy the feature source (api, hooks, types, utils).
  • Build your own UI (recommended), or copy the reference pages/components from the package and adapt.
  • Import data-layer pieces from the package: services, hooks, types, utilities.

UI components and feature constants are deliberately not exported from the public API.


What you get (public API)

Import from the package root:

import {
  objectInfoService,
  objectDetailService,
  useObjectListMetadata,
  useRecordListGraphQL,
  useRecordDetailLayout,
  useObjectColumns,
  useObjectFilters,
  useObjectInfoBatch,
  type FilterCriteria,
  parseFilterValue,
  sanitizeFilterValue,
} from "@salesforce/ui-bundle-template-feature-react-global-search";

API services

  • objectInfoService
    • getObjectInfoBatch(objectApiNames) (GraphQL uiapi.objectInfos)
    • getPicklistValues(objectApiName, fieldName, recordTypeId?) (GraphQL uiapi.objectInfos)
    • getObjectListFilters(objectApiName) (REST search-info filters)
  • objectDetailService
    • getLayout(objectApiName, recordTypeId?) (REST layout)
    • getRecordDetail(objectApiName, recordId, recordTypeId?) (layout + object info + record)
  • GraphQL record helpers
    • getRecordsGraphQL(...) (list query, first + after)
    • getRecordByIdGraphQL(...) (single record by Id)
    • buildWhereFromCriteria(...), buildOrderByFromSort(...), buildGetRecordsQuery(...)

Hooks

  • List metadata: useObjectListMetadata(objectApiName) — filters, columns (derived from filters), picklistValues.
  • List columns (legacy): useObjectColumns(objectApiName) — columns, columnsLoading, columnsError.
  • List filters: useObjectFilters(objectApiName) — filtersData (filters + picklist values per object).
  • List records: useRecordListGraphQL({ objectApiName, first, after, filters, sortBy, searchQuery, columns? }) — GraphQL list with cursor pagination.
  • Detail: useRecordDetailLayout({ objectApiName, recordId, recordTypeId?, initialData? }) — layout (REST) + object metadata + record (GraphQL).
  • Batch object info: useObjectInfoBatch(objectApiNames) — objectInfos, loading, error.

Types, schemas, utils

  • Types: Filter, FilterCriteria, Column, SearchResultRecord, LayoutResponse, ObjectInfoResult, …
  • Zod schemas: LayoutResponseSchema, ObjectInfoResultSchema, SearchResultsResponseSchema, …
  • Utilities: parseFilterValue, sanitizeFilterValue, createFiltersKey, getGraphQLNodeValue, graphQLNodeToSearchResultRecordData, fetchAndValidate, safeEncodePath, getNestedFieldValue, getRecordDisplayName, layout transform and form helpers, etc.

The definitive type surface is in index.d.ts in this package.


Features

  • Single object browse & search: keyword search and “browse all” mode (browse__all).
  • Filterable list: filter definitions + picklist values, criteria → GraphQL where clause.
  • Sortable list: build orderBy from sort selection.
  • Cursor pagination (forward-only) with previous-page simulation via cursor stack.
  • Record detail: layout-driven field selection (layout REST + record GraphQL).
  • Type safety: Zod validation + exported TypeScript types.

Architecture

Data layer (GraphQL vs REST)

  • GraphQL (uiapi)
    Object metadata via getObjectInfoBatch and getPicklistValues. Records via getRecordsGraphQL and getRecordByIdGraphQL.
  • REST (uiApiClient)
    Layout from GET /layout/{object}. Search filters from GET /search-info/{object}/filters. List/search results are GraphQL-only via useRecordListGraphQL (no REST keyword search in the public API).

In the reference implementation:

  • Detail page: useRecordDetailLayoutobjectDetailService.getRecordDetail (layout REST + record GraphQL).
  • List page: useObjectListMetadata (filters + columns + picklists) + useRecordListGraphQL (records).

API flow (conceptual)

  • Initialization: getObjectInfoBatch for object metadata; per object: getObjectListFilters (columns derived from filters), then getPicklistValues for picklist filters.
  • List/search: useRecordListGraphQL (GraphQL UI API with cursor pagination; use a cursor stack for “Previous”).
  • Detail: useRecordDetailLayout / objectDetailService.getRecordDetail.

All API calls use fetchAndValidate and validate with Zod.


Install

npm install @salesforce/ui-bundle-template-feature-react-global-search

Required peer environment

  • @salesforce/ui-bundle (API proxy, auth, etc.)
  • React and React Router

If you are not using that stack, you can still reuse pure utilities and types; the API services and hooks need an equivalent UI API transport.


Configuration (constants)

Constants are not exported. When you build your app (or copy reference UI), define them in the app:

  • OBJECT_API_NAMES – Array of object API names to search. First element is the primary object (e.g. OBJECT_API_NAMES[0]). Default to ["Account"] if no object is specified.
  • DEFAULT_PAGE_SIZE – e.g. 20.
  • DEFAULT_DETAIL_PAGE_TITLE – e.g. "Untitled".

Determining the search object: Decide from the user’s request or app context. If the user does not specify an object, use Account. If your repo provides a script (e.g. scripts/parse-feature-install-context.cjs), you can use it to parse the user prompt and get an object API name or label hint; otherwise set OBJECT_API_NAMES in the app’s constants accordingly.


Vibing integration (recommended: build your own UI)

  1. Routes
    Search results: e.g. /global-search/:query (use browse__all for “show all”). Record detail: e.g. /object/:objectApiName/:recordId.

  2. Search entry
    On submit, navigate to /global-search/${encodeURIComponent(query)} or /global-search/browse__all.

  3. Results page (list)
    Use useObjectListMetadata(objectApiName) for filters/columns/picklists and useRecordListGraphQL({ objectApiName, first, after, filters, sortBy, searchQuery, columns }) for records. Implement a cursor stack for “Previous” (see reference GlobalSearch page).

  4. Detail page
    Use useRecordDetailLayout({ objectApiName, recordId }) for layout, record, objectMetadata; render with layoutTransformUtils and graphQLNodeFieldUtils (or equivalent).

  5. Search input placement
    Put the search entry on the Home page (e.g. as a card) or in the app Headernot in a root layout that wraps every page.


Optional: copy reference UI from the package

The package does not export UI components. If you prefer to copy the reference UI instead of building your own:

  • What to import (do not copy): API (objectInfoService, objectDetailService, …), hooks (useObjectListMetadata, useRecordListGraphQL, useRecordDetailLayout, …), types, Zod schemas, utilities.
  • What to copy into the app: A single constants file (set OBJECT_API_NAMES to your chosen object(s)) and the pages and components from the package’s reference implementation.

Path convention (reference implementation in this repo):

All paths below are relative to the package root of this feature. The reference implementation lives under:

src/force-app/main/default/uiBundles/feature-react-global-search/src/features/global-search/

Example paths:

  • Constants: src/force-app/main/default/uiBundles/feature-react-global-search/src/features/global-search/constants.ts
  • Search page: src/force-app/main/default/uiBundles/feature-react-global-search/src/features/global-search/pages/GlobalSearch.tsx
  • Components: src/force-app/main/default/uiBundles/feature-react-global-search/src/features/global-search/components/

After copying pages/ and components/ into your app:

  1. In the copied files only, replace imports from @/api, @/hooks, @/types, @/utils, @/lib, @/features with imports from @salesforce/ui-bundle-template-feature-react-global-search.
  2. Keep constants and component-to-component imports pointing at your app’s copied constants and components.
  3. Adapt markup and styles to your app’s UI library (the reference uses shadcn and Tailwind).

Example: build filters → FilterCriteria[]

import {
  parseFilterValue,
  sanitizeFilterValue,
  type FilterCriteria,
} from "@salesforce/ui-bundle-template-feature-react-global-search";

function toCriteria(
  objectApiName: string,
  fieldPath: string,
  operator: "eq" | "like",
  rawValues: string[],
): FilterCriteria {
  return {
    objectApiName,
    fieldPath,
    operator,
    values: rawValues
      .map((v) => sanitizeFilterValue(v))
      .filter(Boolean)
      .map((v) => parseFilterValue(v)),
  };
}

Implementation steps (for an agent)

  1. Install
    From the consumer app root: npm install @salesforce/ui-bundle-template-feature-react-global-search.

  2. Determine search object(s)
    From user prompt or app context. Default to Account if none specified. Set OBJECT_API_NAMES in the app’s constants to this value.

  3. Constants
    In the app, create a constants file (or copy from the package reference path above) and set OBJECT_API_NAMES, DEFAULT_PAGE_SIZE, DEFAULT_DETAIL_PAGE_TITLE.

  4. API / types / utils / hooks
    Import only from the package. Do not create or copy api/, hooks/, types/, or utils/ in the app.

  5. UI
    Either (a) build your own UI using the package’s hooks and types, or (b) copy the full pages/ and components/ from the package reference path into the app, then batch-replace imports in the copied files to use the package (see “Optional: copy reference UI” above).

  6. Routes and search input
    Add routes for search (e.g. /global-search/:query) and record detail (e.g. /object/:objectApiName/:recordId). Place the search input on the Home page or in the Header only—not in a root layout.

Checklist

  • [ ] Package installed.
  • [ ] Search object(s) determined; OBJECT_API_NAMES set in app constants.
  • [ ] API, types, utils, hooks imported from package only (no api/hooks/types/utils folders in app).
  • [ ] UI: own implementation or full copy of reference pages/components with imports updated to the package.
  • [ ] Routes and search entry placement done; GlobalSearchInput not in root layout.

Notes / constraints

  • Single-object scope: The package’s APIs and hooks are designed for one CRM object at a time (one objectApiName per call). There is no built-in multi-object search or tabbed results. You can still implement multi-object CRM search by calling the same services and hooks once per object (e.g. in parallel or per tab), then combining the results and building your own UI (tabs, merged lists, or separate sections).
  • Layout is REST: record layout from UI API REST; record and object metadata are GraphQL-backed.
  • No UI exports: build or copy UI in the app; import only the data layer from the package.

Local development (this repo)

When developing this feature inside the ui-bundle repo:

nx run @salesforce/ui-bundle-template-feature-react-global-search:build:dist-app
nx run @salesforce/ui-bundle-template-feature-react-global-search:dev