From e4818bb01a7f7e01ae283f6f8007e82b3ca560c5 Mon Sep 17 00:00:00 2001 From: Luv Kapur Date: Wed, 12 Aug 2026 09:50:10 -0400 Subject: [PATCH 1/2] fix(ui): keep component tabs and use-package tabs reachable on mobile in minimal mode --- .../component-overview.module.scss | 17 +++++++ .../component/ui/menu/menu.module.scss | 45 +++++++++++++++++++ scopes/component/component/ui/menu/menu.tsx | 2 +- .../ui/workspace/workspace.module.scss | 20 +++++++++ 4 files changed, 83 insertions(+), 1 deletion(-) diff --git a/components/ui/component-meta/component-overview.module.scss b/components/ui/component-meta/component-overview.module.scss index 18496f914178..f041828c0e14 100644 --- a/components/ui/component-meta/component-overview.module.scss +++ b/components/ui/component-meta/component-overview.module.scss @@ -43,6 +43,23 @@ .tab { border-bottom: 0; } + + // Mobile: ResponsiveNavbar hides any tab that doesn't fit its container (and reserves extra + // room for its "…" overflow button), so at phone widths the second tab ("Modify component") + // collapses into a bare "…". Sizing the nav to its content makes the width check always pass + // (this wrapper scrolls instead), and the now-useless overflow button is dropped so its + // reserved width can't hide the last tab. + @media screen and (max-width: $br-md) { + overflow-x: auto; + + .nav { + min-width: max-content; + + > div:last-child { + display: none; + } + } + } } .copyBox { diff --git a/scopes/component/component/ui/menu/menu.module.scss b/scopes/component/component/ui/menu/menu.module.scss index aef5463f6392..3963a8d0874c 100644 --- a/scopes/component/component/ui/menu/menu.module.scss +++ b/scopes/component/component/ui/menu/menu.module.scss @@ -17,6 +17,51 @@ min-width: 0; } +// Minimal mode, mobile: one 46px row can't fit breadcrumb + nav tabs + pinned widgets + +// version dropdown, and since only the nav can shrink, ResponsiveNavbar collapses every tab +// (Overview / Preview) into an overflow dropdown that itself gets clipped — leaving no way to +// reach the preview. `display: contents` promotes this bar's children into the workspace +// top bar's wrapping flex row (see workspace.module.scss), producing two rows: +// back + breadcrumb + pinned widgets + right-side actions, then the nav tabs at full width. +.topBarMinimal { + @media screen and (max-width: $br-md) { + display: contents; + + > .leftSide { + order: 10; + flex: 1 0 100%; + box-sizing: border-box; + height: 40px; + overflow-x: auto; + padding: 0 8px 0 4px; + + // ResponsiveNavbar hides any tab that doesn't fit its container and reserves extra room + // for its "…" overflow button. Sizing the nav to its content makes the width check always + // pass (the row scrolls instead), and the now-useless overflow button is dropped so its + // reserved width can't hide the last tab. + nav { + min-width: max-content; + + > div:last-child { + display: none; + } + } + } + + // the pinned widgets carry an inline `height: 100%`, which in the wrapped two-row bar + // resolves against the full (two-row) height and inflates the first row until the nav row + // is pushed outside the bar, over the page content — pin every first-row item to the bar + // height instead + > :not(.leftSide) { + height: 46px !important; + } + + > .rightSide { + margin-left: auto; + } + } +} + .navigation { list-style: none; height: 100%; diff --git a/scopes/component/component/ui/menu/menu.tsx b/scopes/component/component/ui/menu/menu.tsx index 414a7dd716d2..ca94b5267be0 100644 --- a/scopes/component/component/ui/menu/menu.tsx +++ b/scopes/component/component/ui/menu/menu.tsx @@ -168,7 +168,7 @@ export function ComponentMenu({ +
diff --git a/scopes/workspace/workspace/ui/workspace/workspace.module.scss b/scopes/workspace/workspace/ui/workspace/workspace.module.scss index c32b0b00404e..a7db005d8db4 100644 --- a/scopes/workspace/workspace/ui/workspace/workspace.module.scss +++ b/scopes/workspace/workspace/ui/workspace/workspace.module.scss @@ -1,4 +1,5 @@ @import '@teambit/ui-foundation.ui.constants.z-indexes/z-indexes.module.scss'; +@import '@teambit/base-ui.layout.breakpoints/_breakpoints.scss'; .emptyContainer { height: 100vh; @@ -39,6 +40,15 @@ display: flex; align-items: center; height: 100%; + + // when the minimal top bar wraps into two rows on mobile, keep the breadcrumb row at the + // original bar height instead of stretching across both rows, and let a long component + // path clip rather than push the menu actions off-screen + @media screen and (max-width: $br-md) { + height: 46px; + min-width: 0; + overflow: hidden; + } } .breadcrumb { @@ -143,6 +153,16 @@ --bit-bg-heaviest: color-mix(in srgb, var(--bit-accent-color, #6c5ce7) 3%, var(--background-color, #fff)); --bit-border-color-lightest: var(--bit-bg-heaviest); border-bottom: 1px solid var(--border-medium-color, #e6e6e6); + + // Mobile: a single 46px row can't fit breadcrumb + nav tabs + pinned widgets + version + // dropdown. The component menu switches to `display: contents` (see the component menu's + // topBarMinimal in menu.module.scss) so its pieces join this wrapping row: breadcrumb and + // actions stay on the first row, and the nav tabs wrap to a second full-width row. + @media screen and (max-width: $br-md) { + height: auto; + min-height: 46px; + flex-wrap: wrap; + } } } From 384c147e266568624153866b2696f2945b2e0a1b Mon Sep 17 00:00:00 2001 From: Luv Kapur Date: Wed, 12 Aug 2026 10:01:41 -0400 Subject: [PATCH 2/2] fix(ui): lay out the empty-workspace state for narrow viewports --- .../workspace-blank-state.module.scss | 16 +++++++++++++++- 1 file changed, 15 insertions(+), 1 deletion(-) diff --git a/scopes/workspace/workspace/ui/workspace/workspace-overview/workspace-blank-state.module.scss b/scopes/workspace/workspace/ui/workspace/workspace-overview/workspace-blank-state.module.scss index 7afb459f1cbc..a3beaee61eb7 100644 --- a/scopes/workspace/workspace/ui/workspace/workspace-overview/workspace-blank-state.module.scss +++ b/scopes/workspace/workspace/ui/workspace/workspace-overview/workspace-blank-state.module.scss @@ -1,3 +1,5 @@ +@import '@teambit/base-ui.layout.breakpoints/_breakpoints.scss'; + .container { width: 100%; height: 100%; @@ -25,6 +27,10 @@ margin: auto; padding: 48px 32px; text-align: center; + + @media screen and (max-width: $br-sm) { + padding: 32px 20px; + } } .headline { @@ -37,6 +43,10 @@ letter-spacing: -0.02em; text-wrap: balance; + @media screen and (max-width: $br-sm) { + font-size: 34px; + } + em { color: var(--bit-accent-color, #6c5ce7); font-style: italic; @@ -117,7 +127,11 @@ .diyGrid { display: grid; - grid-template-columns: 1fr 1fr; + // auto-fit instead of a bare `1fr 1fr`: `1fr` has an `auto` minimum, so the nowrap command + // text set the column's min width and pushed the second card past the viewport edge on + // narrow screens. 280px is the width at which a full command + Copy button still fit, so + // the cards sit side by side when there's room and stack when there isn't. + grid-template-columns: repeat(auto-fit, minmax(280px, 1fr)); gap: 16px; }