From c0eb3eb2f2a7509ed99f2116e220e9e0509181e2 Mon Sep 17 00:00:00 2001 From: Claude Date: Thu, 3 Sep 2026 16:11:31 +0000 Subject: [PATCH 1/2] feat(types,mobile)!: retire the MobileComponentConfig published type `MobileComponentConfig` published a four-key mobile component-schema extension (`responsive`, `gestures`, `pullToRefresh`, `infiniteScroll`) that nothing read. Re-measured on current main: four code mentions repo-wide (declaration, one doc cross-reference, two barrel re-exports), no mount point, no reader, zero authors in the example apps or the objectstack sibling checkout. Removed outright rather than tombstoned with `?: never`: the whole interface goes, so there is no surviving object to hang a never-key on, and no documentation ever taught it. Same zero-pull, no-successor shape as MobileOverrides (objectui#4919). The dangling `{@link MobileComponentConfig}` cross-reference on MobileResponsiveConfig is rewritten rather than left pointing at a removed name; that type and GestureConfig become zero-consumer published types as a result, recorded as objectui#7519 rather than widened here. Co-Authored-By: Claude Opus 5 Claude-Session: https://claude.ai/code/session_01EMrWaQw3XS5DxTHxp4yRyC --- .../5942-retire-mobile-component-config.md | 66 +++++++++++++++++++ packages/mobile/src/index.ts | 1 - packages/types/src/index.ts | 1 - packages/types/src/mobile.ts | 59 +++++++++++------ 4 files changed, 104 insertions(+), 23 deletions(-) create mode 100644 .changeset/5942-retire-mobile-component-config.md diff --git a/.changeset/5942-retire-mobile-component-config.md b/.changeset/5942-retire-mobile-component-config.md new file mode 100644 index 0000000000..bb33501eb2 --- /dev/null +++ b/.changeset/5942-retire-mobile-component-config.md @@ -0,0 +1,66 @@ +--- +'@object-ui/types': minor +'@object-ui/mobile': minor +--- + +**Removes a published export.** Retire the `MobileComponentConfig` type +(objectui#5942, ADR-0049 enforce-or-remove). The name is deleted from +`@object-ui/types` and from `@object-ui/mobile`, which re-exported it — after +this release `import type { MobileComponentConfig }` from either package is a +compile error, not a deprecation warning. + +`MobileComponentConfig` published a four-key "mobile component schema +extension" — `responsive`, `gestures`, `pullToRefresh` and `infiniteScroll` — +and nothing read it. Re-measured on current `main` before anything was deleted: +the type had exactly four code mentions repo-wide — its own declaration, one +doc-comment cross-reference, and the two barrel re-exports. It had **no mount +point at all**: no type mounted it as a property, nothing extended it, and no +renderer, hook or adapter annotated, cast to or imported it. A sweep of the +example apps and the `objectstack` sibling checkout found zero authors. Every +read-shape probe returned zero against a control lit in the same run. + +That makes it stricter than the usual case: not merely a surface whose values +were unimplemented, but a container with no path by which any authored value +could reach a renderer. objectui#4919 removed its last member +(`mobileOverrides`), which is what left the container itself inert. + +Removed outright rather than kept as a `?: never` tombstone, on this package's +own discriminator: a tombstone steers authors to a named live replacement key +(`crud.ts` `confirm` to `confirmText`; `data-display.ts` `hoverable`/`striped` +to `data-table`), or keeps loud a key the docs taught as working. Neither +applies — the whole interface goes, so there is no surviving object to hang a +`never` key on, and no documentation ever described it +(`skills/objectui/guides/mobile.md` teaches the hooks, never this type). Same +zero-pull, no-successor shape as `MobileOverrides` (objectui#4919) and +`AccordionItem.icon` / `ToggleGroupItem.icon`. + +## Upgrading + +**No behaviour changes and there is nothing to migrate at runtime.** An object +authored against this type did nothing before and does nothing now; what +changes is that the contract no longer claims otherwise, so the mistake +surfaces at authoring time instead of silently type-checking. + +- **You imported the type only** (the only thing that was possible — nothing + accepted it as a value): delete the import. If you kept a local config object + annotated with it, drop the annotation; the object was never passed anywhere + that read it. +- **You actually wanted the behaviour:** it exists, and it is not being + retired. It lives in `@object-ui/mobile` as React hooks, which is where the + working code always was — `useResponsive` / `ResponsiveContainer` for + `responsive`, `useGesture` for `gestures`, `usePullToRefresh` for + `pullToRefresh`. `infiniteScroll` has no hook; it was never implemented in + any form. See `skills/objectui/guides/mobile.md`. +- **You want a declarative mobile config surface:** that re-enters deliberately + as designed product surface on its own card, with the renderer that reads it + landing in the same change as the declaration — not by restoring this + declaration. + +Marked `minor`, not `major`, per this repo's version-alignment rule, which +reserves `major` for following `@objectstack` across a major (AGENTS.md +版本号策略) — the same classification objectui#4919's identically breaking type +removal used. **Breaking for TypeScript consumers of the name only.** + +Follow-up, deliberately not widened into this change: `MobileResponsiveConfig` +and `GestureConfig` were consumed only by this container and are now +zero-consumer published types themselves. Filed as objectui#7519 for triage. diff --git a/packages/mobile/src/index.ts b/packages/mobile/src/index.ts index 7fc4727b7b..370b3f5c2e 100644 --- a/packages/mobile/src/index.ts +++ b/packages/mobile/src/index.ts @@ -65,7 +65,6 @@ export type { GestureType, GestureConfig, GestureContext, - MobileComponentConfig, SpecGestureConfig, SwipeGestureConfig, PinchGestureConfig, diff --git a/packages/types/src/index.ts b/packages/types/src/index.ts index d089ea5235..12abedcdd4 100644 --- a/packages/types/src/index.ts +++ b/packages/types/src/index.ts @@ -623,7 +623,6 @@ export type { GestureType, GestureConfig, GestureContext, - MobileComponentConfig, // The retired `@objectstack/spec/ui` touch vocabulary, now owned here — // see the "Spec Touch Vocabulary" note in `./mobile` (objectstack#4988). // `SPEC_GESTURE_TYPES` is its runtime witness and is exported as a VALUE diff --git a/packages/types/src/mobile.ts b/packages/types/src/mobile.ts index a4f228ef65..a16c70c56a 100644 --- a/packages/types/src/mobile.ts +++ b/packages/types/src/mobile.ts @@ -46,8 +46,14 @@ export type ResponsiveValue = T | Partial>; * `{ breakpoint, hiddenOn, columns: {xs..2xl}, order: {xs..2xl} }` — arranging a * node within a grid. This one is the mobile renderer's box config: `columns` * also accepts a bare number, plus `gap`, `padding`, `stackOnMobile` / - * `stackBreakpoint`, and `hidden`/`showOnly` in place of `hiddenOn`. It is - * consumed only by {@link MobileComponentConfig}. + * `stackBreakpoint`, and `hidden`/`showOnly` in place of `hiddenOn`. + * + * It now has NO consumer. Its only one was `MobileComponentConfig`, retired by + * objectui#5942 (see the RETIRED note below), so this type is still published + * from both barrels and mounted nowhere — the same declared-surface-with-no- + * consumption-path shape #5942 closed, one level down. Recorded as + * objectui#7519 rather than widened into that PR: the name-ownership tripwire + * below outlives the type, and retire-vs-implement here is a product call. * * Tripwire: `__tests__/page-nav-misc-spec-parity.test.ts` fails if the spec ever * claims this name, so the alias cannot outlive its reason. @@ -279,25 +285,36 @@ export interface GestureContext { rotation?: number; } -/** Mobile component schema extension */ -export interface MobileComponentConfig { - /** Responsive configuration */ - responsive?: MobileResponsiveConfig; - /** Touch gesture handlers */ - gestures?: GestureConfig[]; - /** Pull-to-refresh configuration */ - pullToRefresh?: { - enabled: boolean; - threshold?: number; - onRefresh?: string; - }; - /** Infinite scroll configuration */ - infiniteScroll?: { - enabled: boolean; - threshold?: number; - loadMore?: string; - }; -} +// RETIRED (objectui#5942, ADR-0049 enforce-or-remove): `MobileComponentConfig` +// — the free-floating "mobile component schema extension" that published +// `responsive`, `gestures`, `pullToRefresh` and `infiniteScroll` — is gone, not +// narrowed. It never had a MOUNT POINT: no type mounted it as a property, no +// declaration extended it, and nothing in this repo, the example apps or the +// `objectstack` sibling checkout annotated, cast to or imported it outside the +// two barrel re-exports. A value written against it could not reach a renderer +// by any path, so all four keys behaved identically — they did nothing. +// objectui#4919 removed its last member (`mobileOverrides`), which is what left +// the container itself inert. +// +// Removed outright rather than kept as a `?: never` carcass, on this package's +// own discriminator: a tombstone exists to steer authors to a named live +// replacement KEY (`crud.ts` `confirm` -> `confirmText`; `data-display.ts` +// `hoverable`/`striped` -> `data-table`), or to keep loud a key the docs taught +// as working. Neither applies. There is no surviving object to hang a `never` +// key on — the whole interface goes — and no documentation ever described it: +// `skills/objectui/guides/mobile.md` teaches the HOOKS and never this type. +// Same zero-pull, no-successor shape as `MobileOverrides` (objectui#4919), and +// as `AccordionItem.icon` / `ToggleGroupItem.icon` before it. +// +// No BEHAVIOUR is retired here. What the four keys named lives in +// `@object-ui/mobile` as real React hooks — `useResponsive` / +// `ResponsiveContainer`, `useGesture`, `usePullToRefresh` — which is where the +// working code always was; only the declaration nothing read is gone. +// +// Reopen condition: a declarative mobile component-config surface re-enters as +// designed product surface on its own card, with the renderer that READS it +// landing in the same change as the declaration. Re-adding the declaration +// alone is the declare-without-enforce shape this removal exists to close. // ============================================================================ // Spec Touch Vocabulary (formerly `@objectstack/spec/ui`) From 37f82c558a7bbe174c556ffe8cf9cf83cb19e646 Mon Sep 17 00:00:00 2001 From: Claude Date: Thu, 3 Sep 2026 16:58:45 +0000 Subject: [PATCH 2/2] fix(types): make the MobileResponsiveConfig doc self-contained in emitted .d.ts Contract-review patch round. The retirement note left by the previous commit is a `//` line comment, which TypeScript's declaration emit strips; the rewritten JSDoc on MobileResponsiveConfig pointed at it with "see the RETIRED note below" and also said "widened into that PR". Both survive into the PUBLISHED packages/types/dist/mobile.d.ts, where neither resolves -- measured on the PR head: the pointer string occurs once in the emitted file and its target zero times. The JSDoc now carries only references an external reader of the .d.ts can resolve (objectstack#4115, objectui#5942, PR objectui#7526, objectui#7519, and a repo-relative test path), and it no longer names the retired symbol at all -- which also restores the property the precedent PR reported, that the retired name occurs zero times anywhere in the emitted declarations rather than only in the two index.d.ts barrels. Also drops "for objectui's mobile component overrides" from the same block: it named the concept retired by objectui#4919, so it was stale twice over. Changeset gains a warning that TS2724's "Did you mean 'ComponentConfig'?" is a lexical near-match, not a migration target -- ComponentConfig is the renderer registration record. Co-Authored-By: Claude Opus 5 Claude-Session: https://claude.ai/code/session_01EMrWaQw3XS5DxTHxp4yRyC --- .changeset/5942-retire-mobile-component-config.md | 7 +++++++ packages/types/src/mobile.ts | 14 +++++++------- 2 files changed, 14 insertions(+), 7 deletions(-) diff --git a/.changeset/5942-retire-mobile-component-config.md b/.changeset/5942-retire-mobile-component-config.md index bb33501eb2..e9b1486b86 100644 --- a/.changeset/5942-retire-mobile-component-config.md +++ b/.changeset/5942-retire-mobile-component-config.md @@ -56,6 +56,13 @@ surfaces at authoring time instead of silently type-checking. landing in the same change as the declaration — not by restoring this declaration. +**Do not follow the compiler's suggestion.** TypeScript reports the removal from +`@object-ui/types` as TS2724 and appends `Did you mean 'ComponentConfig'?`. That +is a lexical near-match, not a migration target: `ComponentConfig` is the +renderer **registration** record (`{ type: string; component: T }`, extending +`ComponentMeta`) and has nothing to do with mobile configuration. The import +from `@object-ui/mobile` gets a plain TS2305 with no suggestion at all. + Marked `minor`, not `major`, per this repo's version-alignment rule, which reserves `major` for following `@objectstack` across a major (AGENTS.md 版本号策略) — the same classification objectui#4919's identically breaking type diff --git a/packages/types/src/mobile.ts b/packages/types/src/mobile.ts index a16c70c56a..c27cc93c26 100644 --- a/packages/types/src/mobile.ts +++ b/packages/types/src/mobile.ts @@ -35,7 +35,7 @@ export type { BreakpointName }; export type ResponsiveValue = T | Partial>; /** - * Responsive layout configuration for objectui's **mobile component overrides**. + * Responsive layout configuration for the mobile renderer's box layout. * * Renamed off the spec's `ResponsiveConfig` name (objectstack#4115): the two * configure responsiveness through different vocabularies, and this package @@ -48,12 +48,12 @@ export type ResponsiveValue = T | Partial>; * also accepts a bare number, plus `gap`, `padding`, `stackOnMobile` / * `stackBreakpoint`, and `hidden`/`showOnly` in place of `hiddenOn`. * - * It now has NO consumer. Its only one was `MobileComponentConfig`, retired by - * objectui#5942 (see the RETIRED note below), so this type is still published - * from both barrels and mounted nowhere — the same declared-surface-with-no- - * consumption-path shape #5942 closed, one level down. Recorded as - * objectui#7519 rather than widened into that PR: the name-ownership tripwire - * below outlives the type, and retire-vs-implement here is a product call. + * It currently has NO consumer: its only one was retired by objectui#5942 (PR + * objectui#7526), so this type is still exported from `@object-ui/types` and + * `@object-ui/mobile` and is mounted nowhere. Whether it is retired in turn or + * given a renderer is open as objectui#7519 — a product call rather than a + * mechanical one, because the spec name-ownership tripwire named next outlives + * the type either way. * * Tripwire: `__tests__/page-nav-misc-spec-parity.test.ts` fails if the spec ever * claims this name, so the alias cannot outlive its reason.