Skip to content

feat(docs): add opt-in sticky table header, enable on Progress Board - #1992

Open
te6-in wants to merge 3 commits into
devfrom
feat/docs-sticky-header
Open

feat(docs): add opt-in sticky table header, enable on Progress Board#1992
te6-in wants to merge 3 commits into
devfrom
feat/docs-sticky-header

Conversation

@te6-in

@te6-in te6-in commented Aug 11, 2026

Copy link
Copy Markdown
Member

Summary by CodeRabbit

  • 새로운 기능
    • 표에 고정 헤더 옵션을 추가했습니다.
    • 중간 화면 크기 이상에서 헤더가 사이트 헤더 아래에 고정됩니다.
    • 고정 헤더에 불투명 배경과 셀 기준 하단 구분선을 적용했습니다.
    • 고정 헤더 사용 시 가로 콘텐츠를 더욱 편리하게 확인할 수 있습니다.

`TableRoot` gains a `stickyHeader` prop, off by default. When on, the
wrapper becomes a bounded-height scroll box and `thead th` pins to its
top — the only arrangement that works without JS, since `overflow-x-auto`
already makes the wrapper a scroll container in both axes and so captures
any sticky descendant.

The height is capped to the viewport (`100dvh` minus the fumadocs header
row) because a box taller than the screen would carry its pinned header
off-screen with it.

Two rules had to move to the cells, which are what actually stick:

- the row separator lives on `tr` (`[&_tr]:border-b`), so it detached from
  the pinned header and scrolled away; it now sits on `thead th`
- the Progress Board's sticky corner cell needs `z-20!` and its existing
  `bg-…!`, since `[&_thead_th]:` (0,1,2) outranks a plain utility class

Markdown tables are untouched: they never pass the prop, so their wrapper,
`max-height`, and `th` positioning are unchanged.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_018XHskjCS2GuqyqjenH1VJn
@changeset-bot

changeset-bot Bot commented Aug 11, 2026

Copy link
Copy Markdown

⚠️ No Changeset found

Latest commit: 15ecb0d

Merging this PR will not cause a version bump for any packages. If these changes should not result in a new version, you're good to go. If these changes should result in a version bump, you need to add a changeset.

This PR includes no changesets

When changesets are added to this PR, you'll see the packages that this PR includes changesets for and the associated semver types

Click here to learn what changesets are, and how to add one.

Click here if you're a maintainer who wants to add a changeset to this PR

@coderabbitai

coderabbitai Bot commented Aug 11, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro Plus

Run ID: db36f741-7004-49e7-bdae-cff028e29e54

📥 Commits

Reviewing files that changed from the base of the PR and between ee5acfe and 15ecb0d.

📒 Files selected for processing (1)
  • docs/components/table.tsx
🚧 Files skipped from review as they are similar to previous changes (1)
  • docs/components/table.tsx

📝 Walkthrough

Walkthrough

TableRoot에 선택적 sticky 헤더 기능을 추가했습니다. Progress board 테이블은 이 기능을 사용합니다.

Changes

Sticky 헤더 테이블

Layer / File(s) Summary
TableRoot sticky 헤더 구현
docs/components/table.tsx
stickyHeader 옵션과 조건부 스타일을 추가했습니다. 활성화하면 md 이상에서 래퍼의 가로 오버플로를 해제하고, 헤더 셀을 고정하며 불투명 배경과 하단 테두리를 적용합니다.
Progress board 적용
docs/components/progress-board-table.tsx
Progress board 테이블에서 stickyHeader를 활성화했습니다.

Estimated code review effort: 2 (Simple) | ~10 minutes

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed 제목이 옵트인 sticky table header 추가와 Progress Board 적용이라는 주요 변경 사항을 정확히 요약합니다.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
✨ Finishing Touches 💡 1
📝 Generate docstrings 💡
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch feat/docs-sticky-header

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@github-actions

github-actions Bot commented Aug 11, 2026

Copy link
Copy Markdown
Contributor

Alpha Preview (Stackflow SPA)

@github-actions

github-actions Bot commented Aug 11, 2026

Copy link
Copy Markdown
Contributor

Alpha Preview (Storybook)

@github-actions

github-actions Bot commented Aug 11, 2026

Copy link
Copy Markdown
Contributor

Alpha Preview (Docs)

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@docs/components/table.tsx`:
- Line 46: 공유 TableRoot 레시피의 seedStickyHeaderChrome에서 고정된 bg-bg-layer-default
표면색을 제거하고 CSS 변수 참조만 유지하세요. stickyHeader 헤더의 불투명 배경은 보존하되, 실제 변수 값은
wrapperClassName 또는 docs wrapper의 스타일에서 정의해 각 문서 래퍼가 색상을 제어하도록 변경하세요.
🪄 Autofix

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro Plus

Run ID: 91dc60cc-d684-40de-9a18-474f7b6f5ef9

📥 Commits

Reviewing files that changed from the base of the PR and between 64d6dcc and 5ddbd3e.

📒 Files selected for processing (2)
  • docs/components/progress-board-table.tsx
  • docs/components/table.tsx

Comment thread docs/components/table.tsx Outdated
const seedStickyHeaderChrome = clsx(
"[&_thead_th]:sticky [&_thead_th]:top-0 [&_thead_th]:z-10",
// seedTableChrome의 `[&_th]:bg-transparent`를 이겨, 지나가는 본문 행이 헤더 뒤로 비치지 않게 한다
"[&_thead_th]:bg-bg-layer-default",

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

📐 Maintainability & Code Quality | 🟠 Major | ⚡ Quick win

공유 TableRoot 레시피에서 표면색을 고정하지 마세요.

Line 46의 bg-bg-layer-defaultstickyHeader를 사용하는 모든 TableRoot에 표면색을 강제합니다. 헤더의 불투명 배경은 필요하지만, 색상은 docs wrapper의 CSS 변수로 공급해야 합니다. seedStickyHeaderChrome에는 변수 참조만 남기고, wrapperClassName 또는 docs wrapper에서 값을 정의하세요.

As per coding guidelines: "공유 recipe의 표면 색상은 recipe 자체가 아니라 docs wrapper에서 CSS 변수로 중립화한다."

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@docs/components/table.tsx` at line 46, 공유 TableRoot 레시피의
seedStickyHeaderChrome에서 고정된 bg-bg-layer-default 표면색을 제거하고 CSS 변수 참조만 유지하세요.
stickyHeader 헤더의 불투명 배경은 보존하되, 실제 변수 값은 wrapperClassName 또는 docs wrapper의 스타일에서
정의해 각 문서 래퍼가 색상을 제어하도록 변경하세요.

Source: Coding guidelines

The first attempt turned the wrapper into a bounded-height scroll box, so
the table scrolled inside itself. The page should stay the scroll subject
and only the header row should pin under the site header.

That requires the wrapper to stop being a scroll container, which also
gives up horizontal scrolling — so the swap only happens at `md` and up,
where the table fits. Below `md` the wrapper keeps `overflow-x-auto`, the
header does not stick, and the sticky first column still works.

`md` is safe because the table's min-content width is 584px against 720px
of article column there; between 584px and its 678px max-content it only
wraps rather than overflowing. Overflowing would be silent data loss: the
docs layout root is `overflow-x: clip`, so clipped columns get no
scrollbar to reveal them.

The offset comes from fumadocs' `--fd-docs-row-2`, which already tracks
the responsive header height (64/72/76px).

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_018XHskjCS2GuqyqjenH1VJn

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
docs/components/progress-board-table.tsx (1)

94-95: 🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win

좌상단 sticky 헤더 셀의 z-index를 높이세요.

모바일에서 표를 수평 스크롤할 때 뒤의 헤더 셀이 좌상단 셀을 덮을 수 있습니다. TableRootz-10md 이상에서만 적용되며, 좌상단 셀에는 별도 z-index가 없습니다. 해당 셀에 z-20!을 추가하세요.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@docs/components/progress-board-table.tsx` around lines 94 - 95, Update the
sticky top-left header cell in the table markup to add the `z-20!` utility to
its existing className, ensuring it remains above other header cells during
horizontal scrolling on all viewport sizes.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@docs/components/table.tsx`:
- Around line 50-51: In the table styles, update the sticky header border
utility in the thead/th selector to use the exposed
border-palette-static-*-alpha-* token instead of border-stroke-neutral-muted,
choosing a static-alpha value with sufficient contrast in both light and dark
themes. Preserve the existing responsive border placement.

---

Outside diff comments:
In `@docs/components/progress-board-table.tsx`:
- Around line 94-95: Update the sticky top-left header cell in the table markup
to add the `z-20!` utility to its existing className, ensuring it remains above
other header cells during horizontal scrolling on all viewport sizes.
🪄 Autofix

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro Plus

Run ID: 64c1316b-9652-44ba-8a84-e09190a813fa

📥 Commits

Reviewing files that changed from the base of the PR and between 5ddbd3e and ee5acfe.

📒 Files selected for processing (2)
  • docs/components/progress-board-table.tsx
  • docs/components/table.tsx

Comment thread docs/components/table.tsx
Comment on lines +50 to +51
// 구분선은 `[&_tr]:border-b`로 tr에 그려지는데 고정되는 건 th뿐이라 선만 떨어져 스크롤된다. 셀로 옮겨야 헤더를 따라 남는다
"md:[&_thead_th]:border-b md:[&_thead_th]:border-stroke-neutral-muted",

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

📐 Maintainability & Code Quality | 🟠 Major | ⚡ Quick win

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
set -eu

printf '%s\n' '--- target file ---'
sed -n '1,120p' docs/components/table.tsx

printf '%s\n' '--- token references ---'
rg -n --glob '**/*.{tsx,ts,css,md,json}' \
  'border-stroke-neutral-muted|palette-static-[^"'\''[:space:]]*-alpha-[^"'\''[:space:]]*|static-alpha|stroke-neutral-muted' .

printf '%s\n' '--- candidate style/token files ---'
git ls-files | rg '(^|/)(global\.css|.*tailwind.*|.*theme.*|.*token.*|.*seed.*|.*css)$' | head -80

Repository: daangn/seed-design

Length of output: 50375


🏁 Script executed:

#!/bin/bash
set -eu

printf '%s\n' '--- target excerpt from prior output ---'
sed -n '1,100p' /tmp/coderabbit-shell-logs/shell-output-gWA59W

printf '%s\n' '--- tracked source files containing target token ---'
rg -n --glob '!**/dist/**' --glob '!**/build/**' --glob '!**/.next/**' \
  --glob '!**/node_modules/**' --glob '*.{tsx,ts,css,md,json}' \
  'border-stroke-neutral-muted' . | head -80

printf '%s\n' '--- tracked source files containing static-alpha token names ---'
rg -n --glob '!**/dist/**' --glob '!**/build/**' --glob '!**/.next/**' \
  --glob '!**/node_modules/**' --glob '*.{tsx,ts,css,md,json}' \
  'palette-static-[A-Za-z0-9_-]*-alpha-[A-Za-z0-9_]+' . | head -120

printf '%s\n' '--- token/config file candidates ---'
git ls-files | rg '(^|/)(global\.css|.*tailwind.*|.*theme.*|.*token.*|.*seed.*|.*css)$' | head -120

Repository: daangn/seed-design

Length of output: 31226


🏁 Script executed:

#!/bin/bash
set -eu

printf '%s\n' '--- docs global CSS relevant imports and overrides ---'
rg -n -C 4 'tailwind4-theme|seed-design|color-stroke|palette-static|important|thead|table' docs/app/global.css

printf '%s\n' '--- direct static-alpha border utilities in docs source ---'
rg -n --glob 'docs/**/*.{tsx,ts,css,md,mdx}' \
  'border-(palette-static|color-palette-static)|border-(?:[xytrbl]-)?palette-static|palette-static-.*alpha' . | head -120

printf '%s\n' '--- semantic and static token definitions ---'
sed -n '260,290p' packages/lynx-qvism-preset/src/token.css
sed -n '475,500p' packages/lynx-qvism-preset/src/token.css
sed -n '1,115p' packages/tailwind4-theme/index.css

printf '%s\n' '--- theme declarations around token blocks ---'
sed -n '160,225p' packages/lynx-qvism-preset/src/token.css
sed -n '380,435p' packages/lynx-qvism-preset/src/token.css

printf '%s\n' '--- git diff summary ---'
git diff --stat -- docs/components/table.tsx

Repository: daangn/seed-design

Length of output: 22215


🏁 Script executed:

#!/bin/bash
set -eu

printf '%s\n' '--- docs global CSS relevant imports and overrides ---'
rg -n -C 4 'tailwind4-theme|seed-design|color-stroke|palette-static|important|thead|table' docs/app/global.css

printf '%s\n' '--- direct static-alpha border utilities in docs source ---'
rg -n --glob 'docs/**/*.{tsx,ts,css,md,mdx}' \
  'border-(palette-static|color-palette-static)|border-(xytrbl-)?palette-static|palette-static-.*alpha' . | head -120

printf '%s\n' '--- semantic and static token definitions ---'
sed -n '260,290p' packages/lynx-qvism-preset/src/token.css
sed -n '475,500p' packages/lynx-qvism-preset/src/token.css
sed -n '1,115p' packages/tailwind4-theme/index.css

printf '%s\n' '--- theme declarations around token blocks ---'
sed -n '160,225p' packages/lynx-qvism-preset/src/token.css
sed -n '380,435p' packages/lynx-qvism-preset/src/token.css

printf '%s\n' '--- git diff summary ---'
git diff --stat -- docs/components/table.tsx

Repository: daangn/seed-design

Length of output: 22215


🏁 Script executed:

#!/bin/bash
set -eu

python3 - <<'PY'
from pathlib import Path
import re

token_css = Path("packages/lynx-qvism-preset/src/token.css").read_text()
theme_css = Path("packages/tailwind4-theme/index.css").read_text()

def block_after(marker):
    start = token_css.index(marker)
    end = token_css.find("\n}", start)
    return token_css[start:end if end != -1 else len(token_css)]

light = block_after(":root {")
dark_start = token_css.index('`@media` (prefers-color-scheme: dark)')
dark = token_css[dark_start:token_css.find("\n}", dark_start)]

for label, block in [("light", light), ("dark", dark)]:
    match = re.search(
        r"--seed-color-stroke-neutral-muted:\s*var\((--seed-color-palette-static-[^)]+)\)",
        block,
    )
    print(f"{label}: {match.group(1) if match else 'not found'}")

for name in [
    "--color-palette-static-black-alpha-300",
    "--color-palette-static-white-alpha-100",
]:
    print(f"tailwind exposure {name}: {name in theme_css}")
PY

Repository: daangn/seed-design

Length of output: 262


🏁 Script executed:

#!/bin/bash
set -eu

printf '%s\n' '--- token CSS selectors and target declarations ---'
sed -n '1,35p' packages/lynx-qvism-preset/src/token.css
rg -n -C 3 \
  'prefers-color-scheme|data-theme|color-scheme|--seed-color-stroke-neutral-muted' \
  packages/lynx-qvism-preset/src/token.css | head -100

printf '%s\n' '--- focused declaration verifier ---'
python3 - <<'PY'
from pathlib import Path
import re

token_css = Path("packages/lynx-qvism-preset/src/token.css").read_text()
theme_css = Path("packages/tailwind4-theme/index.css").read_text()

matches = re.findall(
    r"--seed-color-stroke-neutral-muted:\s*var\((--seed-color-palette-static-[^)]+)\)",
    token_css,
)
print("stroke-neutral-muted mappings:", matches)

for name in [
    "--color-palette-static-black-alpha-300",
    "--color-palette-static-white-alpha-100",
]:
    print(f"tailwind exposure {name}:", name in theme_css)
PY

Repository: daangn/seed-design

Length of output: 3373


Sticky 헤더 보더를 static-alpha 토큰으로 교체하세요.

md:[&_thead_th]:border-stroke-neutral-muted는 semantic stroke token입니다. Tailwind theme에 노출된 border-palette-static-*-alpha-* 토큰을 사용하고 라이트·다크 테마의 대비를 확인하세요.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@docs/components/table.tsx` around lines 50 - 51, In the table styles, update
the sticky header border utility in the thead/th selector to use the exposed
border-palette-static-*-alpha-* token instead of border-stroke-neutral-muted,
choosing a static-alpha value with sufficient contrast in both light and dark
themes. Preserve the existing responsive border placement.

Source: Coding guidelines

`--fd-docs-row-2` sums the banner and the header on the assumption that
they stack vertically. On this site both are `sticky top-0`, so the header
paints over the banner and the pinned chrome ends at the header's own
height. Using row-2 left a banner-height gap below the site header that
body rows scrolled through.

Only deployments that render the banner show it — locally the banner is
absent, so row-1 is 0 and the two values coincide.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_018XHskjCS2GuqyqjenH1VJn
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