qjudge-mobile-action-footer

star 31

QJudge 前端 mobile button set / sticky action footer 實作技能。當任務涉及手機版底部操作列、Carbon ButtonSet、MobileActionFooter、桌手機 action 分流、避免重複操作按鈕或 mobile CTA 破版時使用。

quan0715 By quan0715 schedule Updated 5/9/2026

name: qjudge-mobile-action-footer description: QJudge 前端 mobile button set / sticky action footer 實作技能。當任務涉及手機版底部操作列、Carbon ButtonSet、MobileActionFooter、桌手機 action 分流、避免重複操作按鈕或 mobile CTA 破版時使用。

QJudge Mobile Action Footer

Quick start

  • 先確認是否是「頁面主要操作」:進入、交卷、儲存、送出、掃描、下載等 CTA 才放進 mobile footer。
  • 優先使用 frontend/src/shared/ui/MobileActionFooter.tsx;若畫面已有自己的 shell footer,使用 frontend/src/shared/ui/MobileButtonSet.tsx。不要在 feature 內重做 ButtonSet layout。
  • Mobile breakpoint 對齊既有實作:useMediaQuery("(max-width: 672px)")
  • Desktop 保留原本內容區 / header actions;mobile 把主要 action 移到 <MobileActionFooter>,避免同一個 action 同時出現兩次。
  • 單一 action 時按鈕佔右半邊、左半邊留空;兩個 actions 時左右各半。不要讓單一按鈕填滿整個底部列,除非該 flow 明確要求全寬 CTA。

Core Pattern

const showMobileActionFooter = useMediaQuery("(max-width: 672px)");

const buildActionSetItems = (): Array<{ key: string; node: ReactNode }> => {
  const candidates = [
    { key: "primary", node: renderPrimaryAction() },
    { key: "secondary", node: renderSecondaryAction() },
  ];

  return candidates.filter((item) => item.node !== null).slice(0, 2);
};

{!showMobileActionFooter ? (
  <DashboardBlock>
    <div className={styles.actionStack}>
      {buildActionSetItems().map((item) => (
        <div key={item.key} className={styles.actionStackItem}>
          {item.node}
        </div>
      ))}
    </div>
  </DashboardBlock>
) : null}

<MobileActionFooter>
  {buildActionSetItems().map((item) => (
    <div key={item.key} className={styles.actionStackItem}>
      {item.node}
    </div>
  ))}
</MobileActionFooter>

Rules

  • Limit mobile footer to 1-2 actions. If there are more, pick the highest-value actions or move overflow into a menu/sheet.
  • Render action nodes from one builder function so desktop and mobile stay behaviorally identical.
  • Use stable keys based on action identity, not array index.
  • Do not show mobile footer and desktop action block at the same breakpoint.
  • Do not put low-frequency links, status-only content, or navigation breadcrumbs in the mobile footer.
  • Keep button sizing controlled by shared MobileButtonSet + Carbon ButtonSet; do not add per-button margins or gaps in feature styles.
  • If single-action right-half placement is not supported by the shared component, update MobileButtonSet once instead of adding invisible placeholder buttons in each page.
  • Bottom button sets must not use Carbon tertiary styles (tertiary or danger--tertiary). Use secondary for low-emphasis actions and danger for destructive submit actions.
  • Add bottom spacer through MobileActionFooter; do not add ad hoc page padding unless a screen has a known fixed overlay.
  • Prefer Carbon button kinds:
    • Primary progress action: kind="primary"
    • Secondary safe action: kind="secondary" or kind="ghost"
    • Utility / document action: kind="ghost"
    • Destructive / irreversible action: kind="danger" or project-approved danger style
  • Icon-only buttons belong in navbar/toolbars, not the mobile action footer, unless the icon is universally clear and has iconDescription.

Layout Checklist

  • One visible source of truth for each action.
  • Footer does not cover the last content row on iOS/Android viewport sizes.
  • Long button labels wrap or truncate acceptably; no text overflow inside Carbon buttons.
  • No nested cards just to host actions.
  • No .cds--* overrides and no !important.
  • Run bash .codex/skills/qjudge-quality-gates-owner/scripts/check-carbon-style.sh after style changes.

When Not To Use

  • Repeated row actions inside tables/lists.
  • Passive status summaries.
  • Desktop-only admin toolbars.
  • Exam runtime controls that must remain visible in a locked navbar unless the user explicitly wants them moved.

Related Skills

  • Use qjudge-ui-carbon-owner for broader Carbon/layout/stories decisions.
  • Use qjudge-carbon-overflow-ux-fix if the footer creates double-scroll or clipped content.
Install via CLI
npx skills add https://github.com/quan0715/QJudge --skill qjudge-mobile-action-footer
Repository Details
star Stars 31
call_split Forks 1
navigation Branch main
article Path SKILL.md
More from Creator