From 66fcafe1de0a59b23d7307f98a086212ccaa062d Mon Sep 17 00:00:00 2001 From: Claude Date: Thu, 5 Nov 2026 19:57:38 +0000 Subject: [PATCH 1/3] refactor(react,fields)!: retire 26 zero-consumer entry exports Barrel batch 4 of the zero-consumer sweep: react 20 names (two dead hook modules, two dead helpers and one dead type deleted), fields 6. Claude-Session: https://claude.ai/code/session_01L6bhgU8CeF9ECf7uDwJLVA Co-authored-by: Claude --- .../25921-fields-zero-consumer-exports.md | 20 +++ .../25921-react-zero-consumer-exports.md | 31 ++++ ui/packages/fields/src/index.tsx | 18 ++- ui/packages/react/src/context/index.ts | 37 ++++- ui/packages/react/src/hooks/index.ts | 7 +- ui/packages/react/src/hooks/useAnimation.ts | 3 - .../react/src/hooks/useKeyboardShortcuts.ts | 22 --- .../react/src/hooks/usePageVariables.tsx | 7 - .../react/src/hooks/useReducedMotion.ts | 53 ------- .../react/src/hooks/useViewTransition.ts | 144 ------------------ ui/packages/react/src/index.ts | 21 ++- 11 files changed, 120 insertions(+), 243 deletions(-) create mode 100644 .changeset/25921-fields-zero-consumer-exports.md create mode 100644 .changeset/25921-react-zero-consumer-exports.md delete mode 100644 ui/packages/react/src/hooks/useReducedMotion.ts delete mode 100644 ui/packages/react/src/hooks/useViewTransition.ts diff --git a/.changeset/25921-fields-zero-consumer-exports.md b/.changeset/25921-fields-zero-consumer-exports.md new file mode 100644 index 00000000000..d2bf37c27ec --- /dev/null +++ b/.changeset/25921-fields-zero-consumer-exports.md @@ -0,0 +1,20 @@ +--- +'@object-ui/fields': patch +--- + +refactor(fields)!: retire six zero-consumer exports (four file-value helpers, the filter-condition extra operators, the grid column sum) + +Clause-②: no (narrowing) +Metadata-protocol: none + + + +**BREAKING** for a host that imports any of these six names from `@object-ui/fields`. None had an importer anywhere in the workspace or in hotcrm, so the Console and every `@object-ui/*` package are unaffected. Every module stays in the package: `FileField`, `ImageField` and `AvatarField` keep reading the file-value helpers, `FilterConditionField` keeps offering its extra operators and `GridField` keeps summing its columns. Only the entry stops publishing them. `fileIdOf`, `fileUrlFromId`, `readFileValue`, `readFileValues`, `fileValueForSubmit`, `isFileIdToken`, `UploadIncompleteError`, the `FileValueView` and `UploadResultLike` types, `condToMongo`, `kvToCondition`, `isMatchAllCriteria`, `FilterConditionField`, `evalArith`, `lookupAutofillPatch`, `computeRow`, `GridField`, `LineItemsField` and the `GridColumn` type stay exported unchanged. + +What leaves, and what to write instead: + +- FROM `isImageValue` TO `readFileValue(value)` and a check on its `mimeType`. +- FROM `uploadResultView`, `withRecentUploads` TO `FileField` / `ImageField` / `AvatarField`, which show a just-uploaded file themselves. +- FROM `FILE_STORAGE_BASE_PATH` TO `fileUrlFromId`, which builds the storage URL for a file id. +- FROM `FILTER_CONDITION_EXTRA_OPERATORS` TO `FilterConditionField`, which offers those operators itself. +- FROM `sumColumn` TO `GridField` / `LineItemsField`, which draw the column totals, or a local reduce over the rows. diff --git a/.changeset/25921-react-zero-consumer-exports.md b/.changeset/25921-react-zero-consumer-exports.md new file mode 100644 index 00000000000..1af431272f5 --- /dev/null +++ b/.changeset/25921-react-zero-consumer-exports.md @@ -0,0 +1,31 @@ +--- +'@object-ui/react': patch +--- + +refactor(react)!: retire twenty zero-consumer exports, and delete the two motion hooks, two helpers and one type nothing reads + +Clause-②: no (narrowing) +Metadata-protocol: none + + + +**BREAKING** for a host that imports any of these twenty names from `@object-ui/react`. None had an importer anywhere in the workspace or in hotcrm, so the Console and every `@object-ui/*` package are unaffected. + +Seven of them are **gone from the package, not only from the entry**, because nothing inside the package read them either: the `hooks/useReducedMotion.ts` module (`useReducedMotion`) and the `hooks/useViewTransition.ts` module (`useViewTransition`, `ViewTransitionConfig`, `ViewTransitionResult`) are deleted, and the functions `useHasPageVariables` and `getShortcutDescriptions` and the type `AnimationTriggerType` are deleted from their modules. + +The other thirteen stay in their modules for the code that reads them and only leave the entry: `formatUnresolvableVisibilityMessage` (the visibility reporter still formats with it), `evaluateConfigBagInScope` (`useConfigBagEvaluator` still calls it), `SUPPORTED_TRANSITION_PRESETS` / `SUPPORTED_EASING_FUNCTIONS` (`useAnimation` still validates with them), `useOptionalTheme`, `resolveNotificationPresentation` and the three `SUPPORTED_NOTIFICATION_*` sets (`NotificationProvider` still uses them), the raw `HostMapStyleContext` / `RecordPagePreferencesContext` / `PrintPageContext` objects, and `NoDataSourcePanel` (`ElementDataSourceGate` still renders it). Every other name the entry exported stays exported unchanged, among them `reportUnresolvableVisibilityPredicate`, `UNRESOLVABLE_VISIBILITY_PREFIX`, `UNRESOLVABLE_ENABLEMENT_PREFIX`, `useAnimation`, `useTheme`, `useNotifications`, `NotificationProvider`, the `HostMapStyleProvider` / `RecordPagePreferencesProvider` / `PrintPageProvider` providers with their `useHostMapStyle` / `useRecordPagePreferences` / `usePrintPage` hooks, `usePageVariables`, `useKeyboardShortcuts` and `ElementDataSourceGate`. + +What leaves, and what to write instead: + +- FROM `useReducedMotion` TO `window.matchMedia('(prefers-reduced-motion: reduce)')` in your own hook; the package no longer carries one. +- FROM `useViewTransition`, `ViewTransitionConfig`, `ViewTransitionResult` TO `document.startViewTransition` called directly; the package no longer carries a wrapper. +- FROM `useHasPageVariables` TO `usePageVariables()`, which answers a frozen empty value outside a `PageVariablesProvider`. +- FROM `getShortcutDescriptions` TO a local map over your `KeyboardShortcutDefinition[]` (filter on `description` and `enabled !== false`). +- FROM `AnimationTriggerType` TO a local string union: no function in the package takes it. +- FROM `formatUnresolvableVisibilityMessage` TO `reportUnresolvableVisibilityPredicate`, which formats and reports in one call; filter its lines by `UNRESOLVABLE_VISIBILITY_PREFIX` / `UNRESOLVABLE_ENABLEMENT_PREFIX`. +- FROM `evaluateConfigBagInScope` TO `SchemaRenderer`, which evaluates a node's config bag itself. +- FROM `SUPPORTED_TRANSITION_PRESETS`, `SUPPORTED_EASING_FUNCTIONS` TO the `TransitionPresetType` / `EasingPreset` types; `useAnimation` already validates the preset. +- FROM `useOptionalTheme` TO `useTheme` inside a `ThemeProvider`. +- FROM `resolveNotificationPresentation`, `SUPPORTED_NOTIFICATION_DISPLAY_TYPES`, `SUPPORTED_NOTIFICATION_POSITIONS`, `SUPPORTED_NOTIFICATION_ACTION_VARIANTS` TO `NotificationProvider` and `useNotificationsByPresentation`, which resolve the presentation and validate the options themselves. +- FROM `HostMapStyleContext`, `RecordPagePreferencesContext`, `PrintPageContext` TO their providers (`HostMapStyleProvider`, `RecordPagePreferencesProvider`, `PrintPageProvider`) and hooks (`useHostMapStyle`, `useRecordPagePreferences`, `usePrintPage`). +- FROM `NoDataSourcePanel` TO `ElementDataSourceGate`, which renders it when no data source resolves, or `noDataSourceMessage` for the text. diff --git a/ui/packages/fields/src/index.tsx b/ui/packages/fields/src/index.tsx index b9cba58b48a..d3fac6ee8bc 100644 --- a/ui/packages/fields/src/index.tsx +++ b/ui/packages/fields/src/index.tsx @@ -5420,7 +5420,18 @@ export * from './widgets/types.js'; // File field value shapes (ObjectStack ADR-0104 D3 wave 2) — the single // arbiter of reference vs expanded vs legacy-blob form, shared by the upload // widgets and by action-param serialization. -export * from './widgets/file-value.js'; +// isImageValue, uploadResultView, withRecentUploads and FILE_STORAGE_BASE_PATH +// stay module-level: the upload widgets read them; no host does. +export { + fileIdOf, + fileUrlFromId, + readFileValue, + readFileValues, + fileValueForSubmit, + isFileIdToken, + UploadIncompleteError, +} from './widgets/file-value.js'; +export type { FileValueView, UploadResultLike } from './widgets/file-value.js'; export * from './FieldEditWidget.js'; export * from './widgets/TextField.js'; export * from './widgets/NumberField.js'; @@ -5445,7 +5456,7 @@ export * from './widgets/RichTextField.js'; export * from './widgets/LookupField.js'; export * from './widgets/CapabilityMultiSelectField.js'; export * from './widgets/ObjectRefField.js'; -export * from './widgets/FilterConditionField.js'; +export { condToMongo, kvToCondition, isMatchAllCriteria, FilterConditionField } from './widgets/FilterConditionField.js'; export * from './widgets/RecipientPickerField.js'; // The kind table and the two spellings the reference widgets share with a host // face (objectui#12613), published so the face names a stored value as the @@ -5484,7 +5495,8 @@ export * from './widgets/AutoNumberField.js'; export * from './widgets/UserField.js'; export * from './widgets/ObjectField.js'; export * from './widgets/VectorField.js'; -export * from './widgets/GridField.js'; +export { evalArith, lookupAutofillPatch, computeRow, GridField, LineItemsField } from './widgets/GridField.js'; +export type { GridColumn } from './widgets/GridField.js'; export * from './widgets/lookupAutofill.js'; // New widgets according to @objectstack/spec export * from './widgets/ColorField.js'; diff --git a/ui/packages/react/src/context/index.ts b/ui/packages/react/src/context/index.ts index 31060ec35b7..57b6e15d547 100644 --- a/ui/packages/react/src/context/index.ts +++ b/ui/packages/react/src/context/index.ts @@ -1,8 +1,34 @@ export * from './SchemaRendererContext.js'; export * from './PreviewModeContext.js'; export * from './ActionContext.js'; -export * from './ThemeContext.js'; -export * from './NotificationContext.js'; +export { ThemeProvider, useTheme } from './ThemeContext.js'; +export type { ThemeContextValue, ThemeProviderProps } from './ThemeContext.js'; +// resolveNotificationPresentation and the three SUPPORTED_NOTIFICATION_* sets +// stay module-level: the provider and its pins read them; no host does. +export { + resolveNotificationConfig, + useNotifications, + useHasNotificationProvider, + visibleNotificationStack, + resolveNotificationPosition, + useNotificationsByPresentation, + NOTIFICATION_PRESENTATIONS, + NotificationProvider, +} from './NotificationContext.js'; +export type { + NotificationSeverityLevel, + NotificationPresentation, + NotificationDisplayType, + NotificationSurface, + NotificationPresentationBehavior, + NotificationPositionValue, + NotificationActionVariant, + NotificationActionButton, + NotificationItem, + NotificationSystemConfig, + ResolvedNotificationConfig, + NotificationProviderProps, +} from './NotificationContext.js'; export * from './DndContext.js'; export * from './AppShellContext.js'; export * from './RecordContext.js'; @@ -10,7 +36,8 @@ export * from './InlineEditContext.js'; export * from './DiscussionContext.js'; export * from './DrillNavigationContext.js'; export * from './HostNavigationContext.js'; -export * from './HostMapStyleContext.js'; -export * from './RecordPagePreferencesContext.js'; +export { useHostMapStyle, HostMapStyleProvider } from './HostMapStyleContext.js'; +export { useRecordPagePreferences, RecordPagePreferencesProvider } from './RecordPagePreferencesContext.js'; +export type { RecordPagePreference, RecordPagePreferencesStore } from './RecordPagePreferencesContext.js'; export * from './RelatedRecordActionsContext.js'; -export * from './PrintPageContext.js'; +export { PrintPageProvider, usePrintPage } from './PrintPageContext.js'; diff --git a/ui/packages/react/src/hooks/index.ts b/ui/packages/react/src/hooks/index.ts index 5203f55271f..aa0524dfd82 100644 --- a/ui/packages/react/src/hooks/index.ts +++ b/ui/packages/react/src/hooks/index.ts @@ -23,14 +23,15 @@ export * from './useDynamicApp.js'; export * from './useDiscovery.js'; export * from './useKeyboardShortcuts.js'; export * from './useCrudShortcuts.js'; -export * from './useReducedMotion.js'; -export * from './useAnimation.js'; +// SUPPORTED_TRANSITION_PRESETS / SUPPORTED_EASING_FUNCTIONS stay module-level +// (their spec-coverage pins import them from the module): no host imports them. +export { useAnimation } from './useAnimation.js'; +export type { EasingPreset, TransitionPresetType, AnimationConfig, AnimationResult } from './useAnimation.js'; export * from './useDensityMode.js'; export * from './useViewSharing.js'; export * from './useOffline.js'; export * from './usePerformance.js'; export * from './usePerformanceBudget.js'; -export * from './useViewTransition.js'; export * from './useETagCache.js'; export * from './useGlobalUndo.js'; export * from './useDebugMode.js'; diff --git a/ui/packages/react/src/hooks/useAnimation.ts b/ui/packages/react/src/hooks/useAnimation.ts index 5dadbd08103..dfc7e64c86c 100644 --- a/ui/packages/react/src/hooks/useAnimation.ts +++ b/ui/packages/react/src/hooks/useAnimation.ts @@ -8,9 +8,6 @@ import { useMemo } from 'react'; -/** Animation trigger type */ -export type AnimationTriggerType = 'enter' | 'exit' | 'hover' | 'focus' | 'click'; - /** * Easing presets aligned with the spec `EasingFunctionSchema` * (`ui/animation.zod.ts` — underscore spellings). The hyphen spellings are diff --git a/ui/packages/react/src/hooks/useKeyboardShortcuts.ts b/ui/packages/react/src/hooks/useKeyboardShortcuts.ts index 29c965b7edd..57a2df8b81f 100644 --- a/ui/packages/react/src/hooks/useKeyboardShortcuts.ts +++ b/ui/packages/react/src/hooks/useKeyboardShortcuts.ts @@ -95,25 +95,3 @@ export function useKeyboardShortcuts( }; }, [enabled, handleKeyDown]); } - -/** - * Returns a list of all registered shortcut descriptions. - * Useful for building a help dialog (? key). - */ -export function getShortcutDescriptions( - shortcuts: KeyboardShortcutDefinition[] -): Array<{ keys: string; description: string }> { - return shortcuts - .filter((s) => s.description && s.enabled !== false) - .map((s) => { - const parts: string[] = []; - if (s.ctrlOrMeta) parts.push('⌘/Ctrl'); - if (s.shift) parts.push('Shift'); - if (s.alt) parts.push('Alt'); - parts.push(s.key.length === 1 ? s.key.toUpperCase() : s.key); - return { - keys: parts.join(' + '), - description: s.description!, - }; - }); -} diff --git a/ui/packages/react/src/hooks/usePageVariables.tsx b/ui/packages/react/src/hooks/usePageVariables.tsx index 70748fbdf47..9da9180df05 100644 --- a/ui/packages/react/src/hooks/usePageVariables.tsx +++ b/ui/packages/react/src/hooks/usePageVariables.tsx @@ -213,13 +213,6 @@ const OUTSIDE_PAGE: PageVariablesContextValue = Object.freeze({ resetVariables: () => {}, }); -/** - * Hook to check if a PageVariablesProvider is available. - */ -export function useHasPageVariables(): boolean { - return useContext(PageVariablesContext) !== null; -} - /** * A writer binding for a page variable, resolved from a component id. */ diff --git a/ui/packages/react/src/hooks/useReducedMotion.ts b/ui/packages/react/src/hooks/useReducedMotion.ts deleted file mode 100644 index 0fb4bc59d37..00000000000 --- a/ui/packages/react/src/hooks/useReducedMotion.ts +++ /dev/null @@ -1,53 +0,0 @@ -/** - * ObjectUI - * Copyright (c) 2024-present ObjectStack Inc. - * - * This source code is licensed under the MIT license found in the - * LICENSE file in the root directory of this source tree. - */ - -import { useState, useEffect } from 'react'; - -/** - * Hook that detects the user's motion preference. - * Implements MotionConfigSchema from @objectstack/spec v2.0.7. - * - * Respects the `prefers-reduced-motion` media query to provide - * accessible animation experiences. - * - * @example - * ```tsx - * function AnimatedCard() { - * const prefersReducedMotion = useReducedMotion(); - * - * return ( - *
- * Content - *
- * ); - * } - * ``` - */ -export function useReducedMotion(): boolean { - const [prefersReducedMotion, setPrefersReducedMotion] = useState(() => { - if (typeof window === 'undefined') return false; - return window.matchMedia('(prefers-reduced-motion: reduce)').matches; - }); - - useEffect(() => { - if (typeof window === 'undefined') return; - - const mediaQuery = window.matchMedia('(prefers-reduced-motion: reduce)'); - - const handleChange = (event: MediaQueryListEvent) => { - setPrefersReducedMotion(event.matches); - }; - - mediaQuery.addEventListener('change', handleChange); - return () => { - mediaQuery.removeEventListener('change', handleChange); - }; - }, []); - - return prefersReducedMotion; -} diff --git a/ui/packages/react/src/hooks/useViewTransition.ts b/ui/packages/react/src/hooks/useViewTransition.ts deleted file mode 100644 index 11f12b8a441..00000000000 --- a/ui/packages/react/src/hooks/useViewTransition.ts +++ /dev/null @@ -1,144 +0,0 @@ -/** - * ObjectUI - * Copyright (c) 2024-present ObjectStack Inc. - * - * This source code is licensed under the MIT license found in the - * LICENSE file in the root directory of this source tree. - */ - -import { useState, useCallback, useMemo } from 'react'; -import { useReducedMotion } from './useReducedMotion.js'; - -// --------------------------------------------------------------------------- -// Types -// --------------------------------------------------------------------------- - -export interface ViewTransitionConfig { - /** Enable view transitions (default: true) */ - enabled?: boolean; - /** Fallback animation class when View Transitions API is unsupported */ - fallbackClass?: string; - /** Transition duration in ms (default: 300) */ - duration?: number; - /** Called before transition starts */ - onTransitionStart?: () => void; - /** Called after transition completes */ - onTransitionEnd?: () => void; -} - -export interface ViewTransitionResult { - /** Whether the View Transitions API is supported */ - isSupported: boolean; - /** Whether a transition is currently in progress */ - isTransitioning: boolean; - /** Execute a callback with a view transition */ - startTransition: (callback: () => void | Promise) => Promise; - /** CSS class to apply during transitions */ - transitionClass: string; -} - -// --------------------------------------------------------------------------- -// Helpers -// --------------------------------------------------------------------------- - -const DEFAULT_DURATION = 300; -const DEFAULT_FALLBACK_CLASS = 'oui-view-transition-fallback'; - -/** Minimal type for the native ViewTransition object returned by the API. */ -interface ViewTransition { - finished: Promise; - ready: Promise; - updateCallbackDone: Promise; -} - -function supportsViewTransitions(): boolean { - return ( - typeof document !== 'undefined' && - 'startViewTransition' in document - ); -} - -// --------------------------------------------------------------------------- -// useViewTransition hook -// --------------------------------------------------------------------------- - -/** - * Hook for integrating with the browser View Transitions API. - * - * Uses the native `document.startViewTransition()` when available and - * falls back to a temporary CSS class for animation when unsupported. - * Respects `prefers-reduced-motion`. - * - * @example - * ```tsx - * function ViewSwitcher({ onViewChange }: { onViewChange: (v: string) => void }) { - * const { startTransition, transitionClass, isTransitioning } = useViewTransition(); - * - * const handleChange = (view: string) => { - * startTransition(() => onViewChange(view)); - * }; - * - * return ( - *
- * ... - *
- * ); - * } - * ``` - */ -export function useViewTransition( - config: ViewTransitionConfig = {}, -): ViewTransitionResult { - const { - enabled = true, - fallbackClass = DEFAULT_FALLBACK_CLASS, - duration = DEFAULT_DURATION, - onTransitionStart, - onTransitionEnd, - } = config; - - const reducedMotion = useReducedMotion(); - const [isTransitioning, setIsTransitioning] = useState(false); - - const isSupported = useMemo(() => supportsViewTransitions(), []); - - const startTransition = useCallback( - async (callback: () => void | Promise): Promise => { - // Skip transition when disabled or user prefers reduced motion - if (!enabled || reducedMotion) { - await callback(); - return; - } - - onTransitionStart?.(); - setIsTransitioning(true); - - try { - if (isSupported) { - // Use native View Transitions API - const transition = (document as Document & { - startViewTransition: (cb: () => void | Promise) => ViewTransition; - }).startViewTransition(callback); - await transition.finished; - } else { - // Fallback: apply class, run callback, remove class after duration - await callback(); - await new Promise((resolve) => setTimeout(resolve, duration)); - } - } finally { - setIsTransitioning(false); - onTransitionEnd?.(); - } - }, - [enabled, reducedMotion, isSupported, duration, onTransitionStart, onTransitionEnd], - ); - - const transitionClass = isTransitioning && !isSupported ? fallbackClass : ''; - - return { - isSupported, - isTransitioning, - startTransition, - transitionClass, - }; -} diff --git a/ui/packages/react/src/index.ts b/ui/packages/react/src/index.ts index 51907cc0ef8..9d3eb873a26 100644 --- a/ui/packages/react/src/index.ts +++ b/ui/packages/react/src/index.ts @@ -6,7 +6,8 @@ * LICENSE file in the root directory of this source tree. */ -export * from './SchemaRenderer.js'; +export { buildNodeEvaluationScope, SchemaErrorBoundary, SchemaRenderer } from './SchemaRenderer.js'; +export type { SchemaRendererProps } from './SchemaRenderer.js'; export * from './schema-input.js'; export * from './hooks/index.js'; // will be empty for now export * from './context/index.js'; // will be empty for now @@ -17,7 +18,22 @@ export * from './data-invalidation.js'; export * from './record-save-feedback.js'; // PageComponentSchema.dataSource — mapping the spec's per-element data binding // onto the schema keys each object-bound block reads (objectstack#6953). -export * from './element-data-source/ElementDataSourceGate.js'; +export { + useElementDataSourceSchema, + ElementDataSourceErrorPanel, + ElementDataSourceLoadingPanel, + useResolvedDataSource, + noDataSourceMessage, + ElementDataSourceGate, + elementDataSourceBlock, +} from './element-data-source/ElementDataSourceGate.js'; +export type { + ElementDataSourceLimitKey, + ElementDataSourceMapping, + UseElementDataSourceSchemaResult, + ElementDataSourceStatusPanelProps, + ElementDataSourceGateProps, +} from './element-data-source/ElementDataSourceGate.js'; // PageComponentSchema.dataSource as the spec's API binding — the read behind // the `data` root `SchemaRenderer` binds for it (objectui#12197). export * from './element-data-source/useElementApiDataSource.js'; @@ -53,7 +69,6 @@ export { isConfigBag } from './utils/configBag.js'; // property the 2026-08-25 ruling asked for. export { reportUnresolvableVisibilityPredicate, - formatUnresolvableVisibilityMessage, UNRESOLVABLE_VISIBILITY_PREFIX, // The ENABLEMENT gate's opening line (objectui#6445). Exported beside its // sibling for the reason that one is: an app filtering these out of its From 4d20b7aece040a7a267c1dabe6778d2545bc42dc Mon Sep 17 00:00:00 2001 From: Claude Date: Thu, 5 Nov 2026 19:58:32 +0000 Subject: [PATCH 2/3] docs(changeset): name what still reads each retired react/fields export Claude-Session: https://claude.ai/code/session_01L6bhgU8CeF9ECf7uDwJLVA Co-authored-by: Claude --- .changeset/25921-fields-zero-consumer-exports.md | 6 +++--- .changeset/25921-react-zero-consumer-exports.md | 7 ++++--- ui/packages/react/src/context/index.ts | 4 ++-- ui/packages/react/src/hooks/index.ts | 4 ++-- 4 files changed, 11 insertions(+), 10 deletions(-) diff --git a/.changeset/25921-fields-zero-consumer-exports.md b/.changeset/25921-fields-zero-consumer-exports.md index d2bf37c27ec..65a2be9d399 100644 --- a/.changeset/25921-fields-zero-consumer-exports.md +++ b/.changeset/25921-fields-zero-consumer-exports.md @@ -9,12 +9,12 @@ Metadata-protocol: none -**BREAKING** for a host that imports any of these six names from `@object-ui/fields`. None had an importer anywhere in the workspace or in hotcrm, so the Console and every `@object-ui/*` package are unaffected. Every module stays in the package: `FileField`, `ImageField` and `AvatarField` keep reading the file-value helpers, `FilterConditionField` keeps offering its extra operators and `GridField` keeps summing its columns. Only the entry stops publishing them. `fileIdOf`, `fileUrlFromId`, `readFileValue`, `readFileValues`, `fileValueForSubmit`, `isFileIdToken`, `UploadIncompleteError`, the `FileValueView` and `UploadResultLike` types, `condToMongo`, `kvToCondition`, `isMatchAllCriteria`, `FilterConditionField`, `evalArith`, `lookupAutofillPatch`, `computeRow`, `GridField`, `LineItemsField` and the `GridColumn` type stay exported unchanged. +**BREAKING** for a host that imports any of these six names from `@object-ui/fields`. None had an importer anywhere in the workspace or in hotcrm, so the Console and every `@object-ui/*` package are unaffected. Every module stays in the package: `FileField`, `ImageField` and `AvatarField` keep reading the file-value helpers, `FilterConditionField` keeps offering its extra operators, `fileUrlFromId` keeps building on the storage base path and `GridField` keeps summing its total column. Only the entry stops publishing them. `fileIdOf`, `fileUrlFromId`, `readFileValue`, `readFileValues`, `fileValueForSubmit`, `isFileIdToken`, `UploadIncompleteError`, the `FileValueView` and `UploadResultLike` types, `condToMongo`, `kvToCondition`, `isMatchAllCriteria`, `FilterConditionField`, `evalArith`, `lookupAutofillPatch`, `computeRow`, `GridField`, `LineItemsField` and the `GridColumn` type stay exported unchanged. What leaves, and what to write instead: - FROM `isImageValue` TO `readFileValue(value)` and a check on its `mimeType`. - FROM `uploadResultView`, `withRecentUploads` TO `FileField` / `ImageField` / `AvatarField`, which show a just-uploaded file themselves. -- FROM `FILE_STORAGE_BASE_PATH` TO `fileUrlFromId`, which builds the storage URL for a file id. +- FROM `FILE_STORAGE_BASE_PATH` TO `fileUrlFromId`, which builds the download URL for a file id on that path. - FROM `FILTER_CONDITION_EXTRA_OPERATORS` TO `FilterConditionField`, which offers those operators itself. -- FROM `sumColumn` TO `GridField` / `LineItemsField`, which draw the column totals, or a local reduce over the rows. +- FROM `sumColumn` TO `GridField`, which draws the total of its declared total column, or a local reduce over the rows. diff --git a/.changeset/25921-react-zero-consumer-exports.md b/.changeset/25921-react-zero-consumer-exports.md index 1af431272f5..b8c82045104 100644 --- a/.changeset/25921-react-zero-consumer-exports.md +++ b/.changeset/25921-react-zero-consumer-exports.md @@ -13,7 +13,7 @@ Metadata-protocol: none Seven of them are **gone from the package, not only from the entry**, because nothing inside the package read them either: the `hooks/useReducedMotion.ts` module (`useReducedMotion`) and the `hooks/useViewTransition.ts` module (`useViewTransition`, `ViewTransitionConfig`, `ViewTransitionResult`) are deleted, and the functions `useHasPageVariables` and `getShortcutDescriptions` and the type `AnimationTriggerType` are deleted from their modules. -The other thirteen stay in their modules for the code that reads them and only leave the entry: `formatUnresolvableVisibilityMessage` (the visibility reporter still formats with it), `evaluateConfigBagInScope` (`useConfigBagEvaluator` still calls it), `SUPPORTED_TRANSITION_PRESETS` / `SUPPORTED_EASING_FUNCTIONS` (`useAnimation` still validates with them), `useOptionalTheme`, `resolveNotificationPresentation` and the three `SUPPORTED_NOTIFICATION_*` sets (`NotificationProvider` still uses them), the raw `HostMapStyleContext` / `RecordPagePreferencesContext` / `PrintPageContext` objects, and `NoDataSourcePanel` (`ElementDataSourceGate` still renders it). Every other name the entry exported stays exported unchanged, among them `reportUnresolvableVisibilityPredicate`, `UNRESOLVABLE_VISIBILITY_PREFIX`, `UNRESOLVABLE_ENABLEMENT_PREFIX`, `useAnimation`, `useTheme`, `useNotifications`, `NotificationProvider`, the `HostMapStyleProvider` / `RecordPagePreferencesProvider` / `PrintPageProvider` providers with their `useHostMapStyle` / `useRecordPagePreferences` / `usePrintPage` hooks, `usePageVariables`, `useKeyboardShortcuts` and `ElementDataSourceGate`. +The other thirteen stay in their modules for the code that reads them and only leave the entry: `formatUnresolvableVisibilityMessage` (the visibility reporter still formats with it), `evaluateConfigBagInScope` (`useConfigBagEvaluator` still calls it), `SUPPORTED_TRANSITION_PRESETS` / `SUPPORTED_EASING_FUNCTIONS` and the three `SUPPORTED_NOTIFICATION_*` sets (the spec-parity tests still hold them against the spec vocabularies, and `resolveNotificationPosition` still checks positions against its set), `useOptionalTheme`, `resolveNotificationPresentation` (`NotificationProvider` still calls it), the raw `HostMapStyleContext` / `RecordPagePreferencesContext` / `PrintPageContext` objects, and `NoDataSourcePanel` (`ElementDataSourceGate` still renders it). Every other name the entry exported stays exported unchanged, among them `reportUnresolvableVisibilityPredicate`, `UNRESOLVABLE_VISIBILITY_PREFIX`, `UNRESOLVABLE_ENABLEMENT_PREFIX`, `useAnimation`, `useTheme`, `useNotifications`, `NotificationProvider`, the `HostMapStyleProvider` / `RecordPagePreferencesProvider` / `PrintPageProvider` providers with their `useHostMapStyle` / `useRecordPagePreferences` / `usePrintPage` hooks, `usePageVariables`, `useKeyboardShortcuts` and `ElementDataSourceGate`. What leaves, and what to write instead: @@ -24,8 +24,9 @@ What leaves, and what to write instead: - FROM `AnimationTriggerType` TO a local string union: no function in the package takes it. - FROM `formatUnresolvableVisibilityMessage` TO `reportUnresolvableVisibilityPredicate`, which formats and reports in one call; filter its lines by `UNRESOLVABLE_VISIBILITY_PREFIX` / `UNRESOLVABLE_ENABLEMENT_PREFIX`. - FROM `evaluateConfigBagInScope` TO `SchemaRenderer`, which evaluates a node's config bag itself. -- FROM `SUPPORTED_TRANSITION_PRESETS`, `SUPPORTED_EASING_FUNCTIONS` TO the `TransitionPresetType` / `EasingPreset` types; `useAnimation` already validates the preset. +- FROM `SUPPORTED_TRANSITION_PRESETS`, `SUPPORTED_EASING_FUNCTIONS` TO the `TransitionPresetType` / `EasingPreset` types, or the spec's `TransitionPresetSchema` / `EasingFunctionSchema` for a runtime list. - FROM `useOptionalTheme` TO `useTheme` inside a `ThemeProvider`. -- FROM `resolveNotificationPresentation`, `SUPPORTED_NOTIFICATION_DISPLAY_TYPES`, `SUPPORTED_NOTIFICATION_POSITIONS`, `SUPPORTED_NOTIFICATION_ACTION_VARIANTS` TO `NotificationProvider` and `useNotificationsByPresentation`, which resolve the presentation and validate the options themselves. +- FROM `resolveNotificationPresentation` TO `useNotificationsByPresentation(presentation)`, which returns the notifications a surface of that presentation renders. +- FROM `SUPPORTED_NOTIFICATION_DISPLAY_TYPES`, `SUPPORTED_NOTIFICATION_POSITIONS`, `SUPPORTED_NOTIFICATION_ACTION_VARIANTS` TO the `NotificationDisplayType` / `NotificationPositionValue` / `NotificationActionVariant` types, or `resolveNotificationPosition` to normalize a position. - FROM `HostMapStyleContext`, `RecordPagePreferencesContext`, `PrintPageContext` TO their providers (`HostMapStyleProvider`, `RecordPagePreferencesProvider`, `PrintPageProvider`) and hooks (`useHostMapStyle`, `useRecordPagePreferences`, `usePrintPage`). - FROM `NoDataSourcePanel` TO `ElementDataSourceGate`, which renders it when no data source resolves, or `noDataSourceMessage` for the text. diff --git a/ui/packages/react/src/context/index.ts b/ui/packages/react/src/context/index.ts index 57b6e15d547..232025518d2 100644 --- a/ui/packages/react/src/context/index.ts +++ b/ui/packages/react/src/context/index.ts @@ -3,8 +3,8 @@ export * from './PreviewModeContext.js'; export * from './ActionContext.js'; export { ThemeProvider, useTheme } from './ThemeContext.js'; export type { ThemeContextValue, ThemeProviderProps } from './ThemeContext.js'; -// resolveNotificationPresentation and the three SUPPORTED_NOTIFICATION_* sets -// stay module-level: the provider and its pins read them; no host does. +// resolveNotificationPresentation and the three SUPPORTED_NOTIFICATION_* sets stay +// module-level for the provider and the spec-parity test; no host imports them. export { resolveNotificationConfig, useNotifications, diff --git a/ui/packages/react/src/hooks/index.ts b/ui/packages/react/src/hooks/index.ts index aa0524dfd82..20db89ede9a 100644 --- a/ui/packages/react/src/hooks/index.ts +++ b/ui/packages/react/src/hooks/index.ts @@ -23,8 +23,8 @@ export * from './useDynamicApp.js'; export * from './useDiscovery.js'; export * from './useKeyboardShortcuts.js'; export * from './useCrudShortcuts.js'; -// SUPPORTED_TRANSITION_PRESETS / SUPPORTED_EASING_FUNCTIONS stay module-level -// (their spec-coverage pins import them from the module): no host imports them. +// SUPPORTED_TRANSITION_PRESETS / SUPPORTED_EASING_FUNCTIONS stay module-level for +// the spec-parity test that imports them from the module; no host imports them. export { useAnimation } from './useAnimation.js'; export type { EasingPreset, TransitionPresetType, AnimationConfig, AnimationResult } from './useAnimation.js'; export * from './useDensityMode.js'; From c5c21494b28a12734334845b7ec677c968ec7b98 Mon Sep 17 00:00:00 2001 From: Claude Date: Thu, 5 Nov 2026 20:03:19 +0000 Subject: [PATCH 3/3] docs(changeset): count the retired react operands exactly Claude-Session: https://claude.ai/code/session_01L6bhgU8CeF9ECf7uDwJLVA Co-authored-by: Claude --- .changeset/25921-react-zero-consumer-exports.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.changeset/25921-react-zero-consumer-exports.md b/.changeset/25921-react-zero-consumer-exports.md index b8c82045104..c0e17c889c8 100644 --- a/.changeset/25921-react-zero-consumer-exports.md +++ b/.changeset/25921-react-zero-consumer-exports.md @@ -7,7 +7,7 @@ refactor(react)!: retire twenty zero-consumer exports, and delete the two motion Clause-②: no (narrowing) Metadata-protocol: none - + **BREAKING** for a host that imports any of these twenty names from `@object-ui/react`. None had an importer anywhere in the workspace or in hotcrm, so the Console and every `@object-ui/*` package are unaffected.