Przeglądaj źródła

fix(web): align queue panel with responsive composer

kingwl 1 miesiąc temu
rodzic
commit
751b970997

+ 20 - 0
apps/web/tests/queue-actions.e2e.ts

@@ -85,6 +85,26 @@ describe('web e2e: queue row actions', () => {
       { timeout: 10_000 },
     ).toBe(2)
 
+    await page.setViewportSize({ width: 640, height: 1000 })
+    const queueBox = await page.locator('[data-queue-dock]').boundingBox()
+    const composerBox = await page.locator('[data-composer-card]').boundingBox()
+    expect(queueBox).not.toBeNull()
+    expect(composerBox).not.toBeNull()
+    expect(queueBox!.x).toBeGreaterThanOrEqual(composerBox!.x)
+    expect(queueBox!.x + queueBox!.width)
+      .toBeLessThanOrEqual(composerBox!.x + composerBox!.width)
+    const queueLeftInset = queueBox!.x - composerBox!.x
+    const queueRightInset = composerBox!.x + composerBox!.width - queueBox!.x - queueBox!.width
+    const composerMetrics = await page.locator('[data-composer-card]').evaluate((element) => {
+      const style = getComputedStyle(element)
+      return {
+        dockInset: Number.parseFloat(style.getPropertyValue('--dsh-composer-dock-inset')),
+      }
+    })
+    expect(queueLeftInset).toBeCloseTo(composerMetrics.dockInset, 1)
+    expect(queueRightInset).toBeCloseTo(composerMetrics.dockInset, 1)
+    await page.setViewportSize({ width: 1680, height: 1000 })
+
     const editRow = page.getByText(EDIT, { exact: true }).locator('..')
     await editRow.getByRole('button', { name: '编辑排队消息' }).click()
     const editor = page.getByRole('textbox', { name: '编辑排队消息' })

+ 14 - 3
packages/client/ui-conversation/src/client/queue/QueueDock.module.css

@@ -1,10 +1,21 @@
-/* Figma .FileContainerText 1:791: 776px wrapper around the inset 752px panel. */
+/* Figma .FileContainerText 1:791: the wrapper uses the shared dock inset
+   inside the composer card around the inset panel. */
 
 .dock {
   box-sizing: border-box;
   flex: none;
-  width: 100%;
-  max-width: 776px;
+  width: calc(
+    100% -
+    var(--dsh-composer-side-clearance) -
+    var(--dsh-composer-side-clearance) -
+    var(--dsh-composer-dock-inset) -
+    var(--dsh-composer-dock-inset)
+  );
+  max-width: calc(
+    var(--dsh-composer-card-max-width) -
+    var(--dsh-composer-dock-inset) -
+    var(--dsh-composer-dock-inset)
+  );
   /* Eat InputBar's 6px top padding and tuck the panel 2px under the card;
      the later composer sibling paints its surface and shadow over this edge. */
   margin: 0 auto -10px;

+ 1 - 1
packages/client/ui-conversation/src/client/queue/QueueDock.tsx

@@ -61,7 +61,7 @@ export function QueueDock({ useSession, updateQueue, notify }: QueueDockProps) {
   }
 
   return (
-    <div className={css.dock}>
+    <div className={css.dock} data-queue-dock="">
       <div className={css.panel}>
         <ul className={css.list}>
           {queue.map(row => (

+ 5 - 0
packages/client/ui-conversation/src/client/skeleton/ConversationRoot.module.css

@@ -131,6 +131,11 @@
 .composerStack {
   display: flex;
   flex-direction: column;
+  /* InputBar and dock registrants derive their horizontal geometry from the
+     same card width, outer clearance, and dock inset. */
+  --dsh-composer-card-max-width: 800px;
+  --dsh-composer-side-clearance: 32px;
+  --dsh-composer-dock-inset: 12px;
 }
 
 /* Common seat for the composer chain (fallback + elected overlay siblings). */

+ 2 - 2
packages/client/ui-conversation/src/client/skeleton/HeroShell.module.css

@@ -11,7 +11,7 @@
   padding: 0 24px;
 }
 
-/* Cap matches InputBar card width (800). Glow may paint past the sides. */
+/* Cap matches the InputBar card. Glow may paint past the sides. */
 .stack {
   display: flex;
   flex-direction: column;
@@ -19,7 +19,7 @@
   /* figma 75:8208: 12 between title block / workspace / card. */
   gap: 12px;
   width: 100%;
-  max-width: 800px;
+  max-width: var(--dsh-composer-card-max-width);
   overflow: visible;
 }
 

+ 5 - 4
packages/client/ui-conversation/src/client/skeleton/InputBar.module.css

@@ -23,7 +23,7 @@
   /* figma Input_Bottom: pad L32/R32/B12; the bottom gradient mask is owned by
      the chat scroller. Top 6 is the gap under the dock todo strip (12px todo
      margin + 6px here); error/status strips still carry their own margin. */
-  padding: 6px 32px 12px;
+  padding: 6px var(--dsh-composer-side-clearance) 12px;
 }
 
 .hero {
@@ -33,7 +33,7 @@
 .error,
 .status {
   width: 100%;
-  max-width: 800px;
+  max-width: var(--dsh-composer-card-max-width);
   margin-bottom: 6px;
   padding: 4px 8px;
   border-radius: 8px;
@@ -48,7 +48,7 @@
 
 .notice {
   width: 100%;
-  max-width: 800px;
+  max-width: var(--dsh-composer-card-max-width);
   margin-bottom: 6px;
   padding: 4px 8px;
   border-radius: 8px;
@@ -69,6 +69,7 @@
 }
 
 .card {
+  box-sizing: border-box;
   position: relative; /* overlay anchor positioning context */
   display: flex;
   flex-direction: column;
@@ -76,7 +77,7 @@
      top pad on the card before .InputText. */
   gap: 12px;
   width: 100%;
-  max-width: 800px;
+  max-width: var(--dsh-composer-card-max-width);
   padding-top: 10px;
   /* Input stroke: black/0.10 light, white/0.06 dark (figma darkmode note says
      the input border is one notch weaker than buttons) — exactly the

+ 14 - 4
packages/client/ui-conversation/src/client/skeleton/TodoPanel.module.css

@@ -1,13 +1,23 @@
 /* Todo strip above the composer (figma 772:51905 / 772:52972 / 772:53419):
-   tip surface, 14px radius, status icons + secondary item labels. Column is
-   calc(100% - 88px) / max 776, centered; InputBar top pad supplies the gap. */
+   tip surface, 14px radius, status icons + secondary item labels. It shares
+   the composer card geometry and adds the dock inset on both sides. */
 
 .root {
   flex: none;
   overflow: hidden;
   margin: 0 auto;
-  width: calc(100% - 88px);
-  max-width: 776px;
+  width: calc(
+    100% -
+    var(--dsh-composer-side-clearance) -
+    var(--dsh-composer-side-clearance) -
+    var(--dsh-composer-dock-inset) -
+    var(--dsh-composer-dock-inset)
+  );
+  max-width: calc(
+    var(--dsh-composer-card-max-width) -
+    var(--dsh-composer-dock-inset) -
+    var(--dsh-composer-dock-inset)
+  );
   border: 1px solid var(--dsw-alias-border-l1);
   border-radius: 14px;
   background: var(--dsw-specific-tip);