Skip to content

feat(lanes | component): re design viewing changes#10378

Draft
luvkapur wants to merge 69 commits into
masterfrom
changes-redesign
Draft

feat(lanes | component): re design viewing changes#10378
luvkapur wants to merge 69 commits into
masterfrom
changes-redesign

Conversation

@luvkapur

Copy link
Copy Markdown
Member

No description provided.

luvkapur and others added 30 commits May 13, 2026 15:56
Defines scope, architecture, hook bindings, and acceptance criteria
(no-drawer, no-monaco, tab rewiring, manual smoke) for porting the
new lane-compare design into ____bit while keeping workspace data
sources.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
16-task plan with explicit scope/name/rootDir per new bit component
so resulting npm package ids match imports from the new design.
Phases A-F cover primitives, non-monaco diff foundation, inline tab
components, compare shell, lane-compare port (drawer stripped), and
final tab-list wiring + acceptance gates.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Ports CompareToolbar from new-changes workspace; adds @teambit/design.inputs.selectors.multi-select@2.0.17 to workspace policy (was missing).

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Ports CompareSidebar (with SidebarGroup and SidebarComponentItem sub-components)
from the new-changes workspace into the component-compare component and exports
all public types from the index.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Add teambit.dependencies/ui/deps-diff-table — a pure table component for rendering dependency diffs between two component versions, with status indicators and compare URL links.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Adds teambit.code/ui/inline-code-compare, which renders per-file inline diffs
using DiffFileRenderer from inline-diff-viewer and wires into ComponentCompare context.
Fixed import path (component.ui.component-compare.component-compare) and removed unused variable.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Ports teambit.review/ui/inline-tests-compare from lane-compare branch; remaps bare component-compare import to component-compare.component-compare package id.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Adds teambit.review/ui/inline-config-compare — renders aspect config/data
diffs between two component versions using DiffFileRenderer.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…eHeader

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Required by InlineComponentCompare (Task 12). bit install side-effects.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Adds teambit.semantics/ui/api-diff-view — a full-pane React component that queries and renders API surface changes between two component versions using GQL.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…e data

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…hapes

- Drop `isMerged` references from lane-compare-page (LaneModel only has `deleted`)
- Adapt `useLaneComponents` call to single-arg signature returning an object
- Use `componentDescriptors` (not `components`) for the compositions map since `.get()` is a ComponentDescriptor method

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…hema

InlineContextProvider and EagerFileRegistrar used useGetComponents /
createComponentModel from the cloud GraphQL schema (getComponents /
CompDescriptor), which the workspace/scope dev-server schema does not
expose - every InlineComponentCompare fired a 400, breaking the code
diff and stalling the lane-diff query via a re-render storm.

Replace with the schema-compatible useComponent hook (spec section 7.1
fallback). Drop the now-unused cloud packages from workspace.jsonc.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Extract workspace-overview's data-agnostic pieces into a shared
@teambit/explorer.ui.components-overview component; refactor both
workspace-overview and lane-overview into thin adapters.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
… plan

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
…rview

Creates @teambit/explorer.ui.components-overview with data-agnostic card,
filter-panel, aggregation hooks, and a new ComponentsOverview orchestrator
that accepts getHref / storageNamespace injection points.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…onent

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Wraps the header slot and filter command bar in a single sticky div,
measures its height via ResizeObserver into --components-overview-sticky-height,
and uses that CSS var as the top offset for section headers.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
luvkapur and others added 30 commits May 14, 2026 14:47
Threads an optional `context` prop through UseComponentOptions →
useComponent → useComponentQuery → useComponentLogs, forwarding it into
each useDataQuery call so callers can opt queries into Apollo request
batching (e.g. `context: { batch: true }`). Purely additive; existing
callers are unaffected.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Replace per-component EagerFileRegistrar/EagerAspectRegistrar with RegistryFeeder
(bulk context) + NewComponentFileRegistrar (new-only). InlineContextProvider now
reads from useCompareData() instead of firing per-component GraphQL queries.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…ng in registrars

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- lane-compare: render panels independent of the active view mode and drive
  per-view visibility via CSS (stable data-has-* attrs + content-visibility),
  so switching views is a CSS attribute flip instead of a panel remount plus a
  ~1.2s forced layout reflow
- component-compare: stable `dataAttributes` passthrough on InlineComponentCompare
- deps-diff-table: key rows by id+lifecycle+status (fixes duplicate-key warning)
- tooltip: wrap non-ref children (e.g. Icon) in a span (fixes "Function
  components cannot be given refs")
- import component.ui.component-meta so the docs overview consumes the workspace
  (fixed) tooltip; minor type guards to satisfy workspace lint

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Conflicts resolved:
- docs.ui.runtime.tsx: combine the LanesUI provider dep (ours) with master's
  config typing + usePreviewProps slot
- react webpack.config.base.ts: drop react-dom/server alias (master), keep the
  lane-diff dedupe alias (ours)
- workspace.tsx: single `const location = useLocation()`; relocated
  if(!workspace)/setComponents block kept once

Reconciled deps to @types/react ^19 (bit install) and fixed two typings the bump
surfaced: useRef<T>() initial arg (file-registry) and MultiSelect Option->SelectOption
cast (compare-toolbar). pnpm-lock.yaml kept at origin/master (not committed on the branch).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
It was pinned in workspace.jsonc to a lane-only snap (0.0.0-bfaed620…, on
teambit.review/new-changes) that was never published to the registry, so CI's
fresh install 404'd while local resolved it from cache. Recreated the component
from the new-changes lane source as a teambit.preview workspace component so CI
builds it from source; removed the snap pin. pnpm-lock.yaml untouched.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
The redesign added LanesAspect to the docs aspect's `static dependencies`, but the
resolved `lanesUi` was never used. docs is widely depended upon and lanes already
depends on docs (lane-compare consumes the inline-docs compare tab), so this
docs→lanes edge formed a cycle that pulled lanes/merge-lanes/checkout/merging into
the workspace cycle (62 → 66). Removed the unused dependency (import, static dep,
and provider param).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…main advances

The redesign's diffStatus result-memo keyed the main target as a constant 'default'
(no single lane hash exists for main), so when main moved ahead the key never changed
and a stale "up to date" result was served — lanes.spec's "not up to date when main is
ahead" failed (expected true to be false, 2 assertions).

Resolve the per-component main heads before computing the memo key and fingerprint them
into it (lane-vs-lane keys are unchanged — both heads were already captured). No
resolvable main heads ⇒ skip the result memo. Verified locally: the 4 isLaneUpToDate/
laneDiff tests pass.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
The env's EslintLint (stricter than the repo's oxlint) failed on the redesign's
component-compare, and lane-compare's lint was skipped only because its dependency
(component-compare) failed first — so its errors would surface next run. Fixed both:

- component-compare (compare-sidebar/component-compare/file-registry): no-plusplus,
  consistent-return (return undefined), no-param-reassign (ref forwarding), curly-brace
  presence, a11y keyboard support on the chevron, and file-level no-use-before-define
  disable for hoisted function components.
- lane-compare: removed dead _getChangeTags + unused _contextGroupBy, converted for-of
  loops to forEach (no-restricted-syntax), replaced statement-ternary with if/else, and
  unnested the group-key and sidebar-files ternaries.

Verified: bit lint clean (0 errors) on both; repo tsc+oxlint green.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
The useEffect returned a cleanup in one path but bare `return;` in the guard path,
tripping eslint consistent-return (build EslintLint). Return undefined explicitly.
Swept the rest of the redesign components — no other eslint errors remain.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
# Conflicts:
#	pnpm-lock.yaml
#	scopes/workspace/workspace/ui/workspace/workspace-overview/workspace-overview.tsx
The lockfile re-resolution bumped oxlint 1.61 -> 1.68 within the ^1.61.0
range, and 1.68's no-unreachable rule flags dead statements after
return/throw that 1.61 missed.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
…slot

- semantic-schema-diff: APIDiffResult gains status/base/compare availability;
  computeAPIDiff short-circuits when a schema is missing instead of fabricating
  a diff; impact derived from public changes only, internalImpact added
- schema aspect: getSchemaWithAvailability maps each silent-empty branch to a
  reason (NOT_BUILT/NO_EXTRACTOR/DISABLED/FAILED); GraphQL exposes the new fields
- component-compare main: drop pre-availability disk-memo entries (no status)
- api-diff-view: rewritten as master-detail content pane — per-component
  sections with change blocks (signature diff, cause facts, impact), slim
  component-level rows for no-changes/no-data/error/internal-only, progressive
  loading, sidebar scroll-sync via data-file-id anchors, ApiDiffInsightProvider
- lane-compare: API view reuses CompareSidebar (exports nested like files),
  pre-gates apiDiff queries by lane-diff change types
- component-compare ui runtime: ApiDiffInsightSlot + registerApiDiffInsight
- api-reference: APICompare is now a thin host over ComponentApiDiffSection;
  duplicated APIDiff types/queries removed repo-wide (single model in
  semantics.ui.api-diff-view)

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Data layer:
- bit schema diff CLI is availability-aware: reports which side lacks API data
  and why, instead of fabricating a full-surface diff (or a false 'no changes')
- never persist transient FAILED-availability results: component-compare's disk
  memo skips them, lanes' boolean memo skips them and its lane-diff-api-diff.json
  is versioned (v2) so pre-redesign fabricated verdicts are discarded on load
- SchemaMain.computeAPIDiff gains an in-memory single-flight memo (immutable,
  built pairs only) — lane-diff status and the compare UI no longer run schema
  extraction twice for the same pair on a cold load

UI:
- memoize getApiDiffInsights / stable EMPTY_INSIGHTS so LaneCompare's React.memo
  survives (was re-rendering the whole compare tree every render)
- skipped diffs (same version both sides) render an anchored slim row instead of
  vanishing; same-version pairs are pre-gated client-side
- stable-state no longer unmounts rows — sidebar scroll anchors always exist
- failed queries are excluded from the 'N components analyzed' stable hero and
  suppress it entirely; totals/progress computed only over the current diff set
- 'not comparable' copy for unrelated/removed components (vs 'new component');
  empty change-type arrays query instead of being assumed unchanged
- counts.api covers all components so the auto-view-switch can't yank users away
  from the API view's own empty state; file/export selection clears on view switch
- both unavailable reasons shown when sides differ; dark-theme-safe signature
  diff tints via color-mix; drop unused useApiEntriesRegister hook

Tests: visibility-move drives public impact; getSchemaWithAvailability
reason-mapping per branch (DISABLED/NO_EXTRACTOR/FAILED/NOT_BUILT/available/
alwaysRunExtractor rethrow)

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant