Skip to content

DataViews: remove all private API usage #81230

Description

@youknowriad

@wordpress/dataviews is a bundled package — it declares neither wpScript nor wpModuleExports in its package.json. Per AGENTS.md:

Avoid using private APIs in bundled packages (packages without wpScript or wpModuleExports). Private APIs are intended for Core usage; bundled packages may also be imported via npm into plugin scripts, causing incompatibilities.

Concretely: lockedData is a module-scoped WeakMap and __private is a plain Symbol() — not Symbol.for() (implementation.ts#L187-L193). Two copies of @wordpress/private-apis in one runtime cannot unlock each other's objects, so a plugin that loads wp.components from the WP global alongside a bundled DataViews throws Cannot unlock an object that was not locked before at module-eval time, before anything renders.

Secondary cost: unlock() is typed <T = any>( object: unknown ): T, so every unlocked symbol lands as any. All 23 call sites below are effectively unchecked by TypeScript — swapping any of them for a public equivalent tends to surface pre-existing type mismatches.

@wordpress/components

18 of the 25 symbols in components/src/private-apis.ts, across 21 production files:

Symbol Where Why it's private
Menu add-filter.tsx:22, dataviews-view-config/index.tsx:37, dataviews-item-actions/index.tsx:27, column-header-menu.tsx:33, list/index.tsx:62 Ariakit-based menu; no public replacement exists yet — @wordpress/ui has no menu
Badge picker-grid/index.tsx:36, composite-grid.tsx:45 A public Badge already ships in @wordpress/ui and DataViews uses it in validation-badge.tsx — this one is a stale holdout
kebabCase dataviews-item-actions/index.tsx:27 String util, private to avoid committing to a public utils surface
DateCalendar, DateRangeCalendar date.tsx:57, datetime.tsx:24 New calendar components still stabilizing
withIgnoreIMEEvents richtext/control.tsx:47 IME keydown wrapper
Validated* × 12 one per control in dataform-controls/InputControl, Checkbox, Combobox, Number, Select, Radio, ContentEditable, Textarea, Toggle, ToggleGroup, FormTokenField (+Text in a story) The whole validated-form-controls layer is private; DataForm is its only real consumer

@wordpress/rich-text

5 of the 9 symbols in rich-text/src/private-apis.js, all in one file — dataform-controls/richtext/control.tsx:

Symbol Where Why it's private
useRichText richtext/control.tsx:61 Core editing hook; the public surface is RichText in @wordpress/block-editor, which DataViews can't depend on
KeyboardShortcutContext, InputEventContext richtext/control.tsx:61 The same context objects that format types' RichTextShortcut / RichTextInputEvent read
shortcutsListener, inputEventsListener richtext/control.tsx:61 Dispatch the registered callbacks from the editable element's own events

Exposed by DataViews

Symbol Where Notes
RichTextControl locked in dataviews/src/private-apis.ts, unlocked by editor note-form.js:28 DataViews' own private export — one symbol, one consumer. Needs to become a public export or move to the consumer

Todo

Ordered by effort — the first three are unblocked today.

Metadata

Metadata

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions