Skip to content

feat: 优化UI组件样式和交互体验#128

Merged
AmintaCCCP merged 9 commits intoAmintaCCCP:mainfrom
SummerRay160:Dev
Apr 30, 2026
Merged

feat: 优化UI组件样式和交互体验#128
AmintaCCCP merged 9 commits intoAmintaCCCP:mainfrom
SummerRay160:Dev

Conversation

@SummerRay160
Copy link
Copy Markdown
Contributor

@SummerRay160 SummerRay160 commented Apr 29, 2026

refactor(RepositoryCard): 增强工具提示在浅色模式下的可读性
feat(ReadmeModal): 添加字体大小类型支持
style(index.css): 改进文本区域和输入框的浅色模式样式
refactor(MarkdownRenderer): 移除行号显示并支持字体大小调整
refactor(RepositoryEditModal): 优化浅色模式下的表单样式和交互

Summary by CodeRabbit

  • New Features

    • Configurable font sizes for rendered content (small, medium, large).
  • Improvements

    • Restyled repository description tooltip for improved light‑mode readability.
    • Enhanced form/input UX: focus rings, textarea scrolling/resize, mobile text sizing, custom scrollbars, and print styles.
    • Updated modal and button visuals for consistency.
    • App shows a loading placeholder until persisted state hydrates.
    • Adjusted tooltip/dropdown stacking and refreshed AI-search tooltip styling/content.
    • Simplified code block rendering to a cleaner single-block display.
  • Bug Fixes

    • Image retry now prevents navigation and reliably reloads images.

refactor(RepositoryCard): 增强工具提示在浅色模式下的可读性
feat(ReadmeModal): 添加字体大小类型支持
style(index.css): 改进文本区域和输入框的浅色模式样式
refactor(MarkdownRenderer): 移除行号显示并支持字体大小调整
refactor(RepositoryEditModal): 优化浅色模式下的表单样式和交互
@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai Bot commented Apr 29, 2026

Note

Reviews paused

It looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the reviews.auto_review.auto_pause_after_reviewed_commits setting.

Use the following commands to manage reviews:

  • @coderabbitai resume to resume automatic reviews.
  • @coderabbitai review to trigger a single review.

Use the checkboxes below for quick actions:

  • ▶️ Resume reviews
  • 🔍 Trigger review
📝 Walkthrough

Walkthrough

Adds a font-size prop to MarkdownRenderer and threads it from ReadmeModal; simplifies code-block rendering and image retry handling; restyles repository tooltips and edit-modal UI; introduces form-focused global CSS; adjusts SearchBar tooltip/z-index; adds persisted-store hydration flag and gates App rendering until hydrated.

Changes

Cohort / File(s) Summary
Markdown rendering
src/components/MarkdownRenderer.tsx, src/components/ReadmeModal.tsx
Added `fontSize?: 'small'
Repository UI & edit modal
src/components/RepositoryCard.tsx, src/components/RepositoryEditModal.tsx
Repository tooltip restyled to a light theme (padding, typography, rounded corners, fade-in, constrained height + scroll, arrow changes). RepositoryEditModal consolidates shared UI classes, updates textarea to vertical resize with min/max/scroll and larger default rows, and refreshes footer/button visuals and spacing.
Global form styles
src/index.css
Adds selection colors, explicit focus rings for inputs/selects/textareas, smooth/iOS scrolling, WebKit textarea scrollbar & resize-handle styling (with dark variants), placeholder color, mobile font-size safeguard, and print-specific input/textarea rules.
Search & UI stacking
src/components/SearchBar.tsx
Adjusted z-indexes for dropdown and search wrapper; restyled AI-search tooltip container/arrow and simplified tooltip copy/logic; updated sort controls stacking context.
App hydration & store
src/App.tsx, src/store/useAppStore.ts
Introduces hasHydrated: boolean and setHasHydrated action in store; wires onRehydrateStorage to set the flag. App now returns a loading placeholder until hasHydrated is true.

Sequence Diagram(s)

sequenceDiagram
  participant Persistence as Persistence (localStorage)
  participant Store as useAppStore
  participant App as App component
  participant UI as Main UI

  Note over Persistence,Store: Rehydration flow
  Persistence->>Store: onRehydrateStorage(callback)
  Store->>Persistence: subscribe
  Persistence-->>Store: rehydrate complete
  Store->>Store: setHasHydrated(true) rgba(34,139,34,0.5)
  Store->>App: hasHydrated = true
  App->>UI: render main UI
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

Possibly related PRs

Poem

🐰 I nibble prose and tidy every line,
I fold the codeblocks neat where numbers once shined,
I stop a wandering click and stitch the image back,
I fluff the textareas and polish tooltip tracks —
A hop, a tweak, the UI feels aligned.

🚥 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 The title 'feat: 优化UI组件样式和交互体验' translates to optimizing UI component styles and interaction experience, which is a broad and accurate summary of the changes across multiple files in this PR.
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.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

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 and usage tips.

Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai Bot left a comment

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)
src/components/RepositoryEditModal.tsx (1)

666-667: ⚠️ Potential issue | 🟡 Minor

Fix malformed Tailwind class strings in reset state UI.

Lines 666, 791–792, and 888–889 contain concatenated utility tokens missing spaces, preventing these styles from being generated and causing light-mode states to regress.

Proposed fix
-              <span className="inline-flex items-center px-2 py-0.5 text-[11px] font-medium bg-light-surfacetext-gray-900 dark:bg-white/[0.04] dark:text-text-secondary rounded-full">
+              <span className="inline-flex items-center px-2 py-0.5 text-[11px] font-medium bg-light-surface text-gray-900 dark:bg-white/[0.04] dark:text-text-secondary rounded-full">

-                    ? 'bg-light-surfacetext-gray-900border-black/[0.06] dark:bg-white/10 dark:text-text-primary dark:border-white/20'
-                    : 'bg-white text-gray-700border-black/[0.06] hover:bg-light-bg dark:bg-white/[0.04] dark:text-text-secondary dark:border-white/[0.04] dark:hover:bg-white/10 dark:hover:text-gray-900'
+                    ? 'bg-light-surface text-gray-900 border-black/[0.06] dark:bg-white/10 dark:text-text-primary dark:border-white/20'
+                    : 'bg-white text-gray-700 border-black/[0.06] hover:bg-light-bg dark:bg-white/[0.04] dark:text-text-secondary dark:border-white/[0.04] dark:hover:bg-white/10 dark:hover:text-gray-900'

-                    ? 'bg-light-surfacetext-gray-900border-black/[0.06] dark:bg-white/10 dark:text-text-primary dark:border-white/20'
-                    : 'bg-white text-gray-700border-black/[0.06] hover:bg-light-bg dark:bg-white/[0.04] dark:text-text-secondary dark:border-white/[0.04] dark:hover:bg-white/10'
+                    ? 'bg-light-surface text-gray-900 border-black/[0.06] dark:bg-white/10 dark:text-text-primary dark:border-white/20'
+                    : 'bg-white text-gray-700 border-black/[0.06] hover:bg-light-bg dark:bg-white/[0.04] dark:text-text-secondary dark:border-white/[0.04] dark:hover:bg-white/10'
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/components/RepositoryEditModal.tsx` around lines 666 - 667, The Tailwind
class strings in RepositoryEditModal.tsx are malformed (utility tokens
concatenated without spaces) in the span wrapping the FileText icon and two
other similar span elements, which prevents Tailwind from generating the
light-mode styles; open RepositoryEditModal.tsx, locate the span with the
FileText component and the other two span elements that have concatenated tokens
in their className props, and fix each className by inserting the missing spaces
between utility tokens (preserving the intended light/dark classes and order) so
each Tailwind utility is a separate token and styles are applied correctly.
🧹 Nitpick comments (2)
src/components/RepositoryCard.tsx (1)

879-898: Add keyboard-triggered tooltip behavior for truncated text.

Line 879-Line 898 only opens the tooltip on mouse hover. Consider adding focus/blur support (and role="tooltip" linkage) so keyboard users can also access full truncated descriptions.

Suggested accessibility-focused patch
-        <div
-          className="relative group"
-          onMouseEnter={() => isTextTruncated && setShowTooltip(true)}
-          onMouseLeave={() => setShowTooltip(false)}
-        >
+        <div
+          className="relative group"
+          onMouseEnter={() => isTextTruncated && setShowTooltip(true)}
+          onMouseLeave={() => setShowTooltip(false)}
+          onFocusCapture={() => isTextTruncated && setShowTooltip(true)}
+          onBlurCapture={() => setShowTooltip(false)}
+        >
           <p
             ref={descriptionRef}
+            tabIndex={isTextTruncated ? 0 : -1}
+            aria-describedby={isTextTruncated ? `repo-desc-tooltip-${repository.id}` : undefined}
             className="text-gray-800 dark:text-text-secondary text-[13px] leading-[1.625] line-clamp-3 mb-2 transition-colors duration-200 hover:text-gray-900 dark:hover:text-text-primary rounded px-1 -mx-1 hover:bg-gray-50/50 dark:hover:bg-white/[0.02]"
           >
             {highlightSearchTerm(displayContent.content, searchQuery)}
           </p>

           {isTextTruncated && showTooltip && (
-            <div className="absolute z-50 bottom-full left-0 right-0 mb-2 p-4 bg-white dark:bg-surface-3 text-gray-900 dark:text-text-primary text-[13px] leading-[1.625] rounded-xl shadow-dialog border border-gray-200/80 dark:border-white/[0.04] animate-fade-in max-h-[280px] overflow-y-auto scrollbar-auto">
+            <div
+              id={`repo-desc-tooltip-${repository.id}`}
+              role="tooltip"
+              className="absolute z-50 bottom-full left-0 right-0 mb-2 p-4 bg-white dark:bg-surface-3 text-gray-900 dark:text-text-primary text-[13px] leading-[1.625] rounded-xl shadow-dialog border border-gray-200/80 dark:border-white/[0.04] animate-fade-in max-h-[280px] overflow-y-auto scrollbar-auto"
+            >
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/components/RepositoryCard.tsx` around lines 879 - 898, The tooltip
currently only opens on mouse hover; add keyboard accessibility by making the
truncated paragraph focusable and linking it to the tooltip: add tabIndex={0}
and onFocus={() => isTextTruncated && setShowTooltip(true)} and onBlur={() =>
setShowTooltip(false)} to the element using descriptionRef (the <p> with
ref={descriptionRef}), generate a stable tooltip id (useId or state like
tooltipId) and set aria-describedby={isTextTruncated && showTooltip ? tooltipId
: undefined} on that <p>, give the tooltip div role="tooltip" and
id={tooltipId}, and add an onKeyDown handler on the <p> to close the tooltip on
Escape by calling setShowTooltip(false); keep existing mouse handlers and
highlightSearchTerm usage unchanged.
src/components/ReadmeModal.tsx (1)

54-65: Consider removing index-to-type duplication to avoid drift.

getFontSizeType() re-encodes fontSizeIndex mapping that is already implied by FONT_SIZES. If sizes/order change, these can diverge.

Refactor sketch
-const FONT_SIZES = [
-  { label: '小', labelEn: 'Small', value: 'text-sm' },
-  { label: '中', labelEn: 'Medium', value: 'text-base' },
-  { label: '大', labelEn: 'Large', value: 'text-lg' },
-];
+const FONT_SIZES = [
+  { label: '小', labelEn: 'Small', value: 'text-sm', type: 'small' as const },
+  { label: '中', labelEn: 'Medium', value: 'text-base', type: 'medium' as const },
+  { label: '大', labelEn: 'Large', value: 'text-lg', type: 'large' as const },
+];

-const getFontSizeType = useCallback((): 'small' | 'medium' | 'large' => {
-  switch (fontSizeIndex) {
-    case 0:
-      return 'small';
-    case 2:
-      return 'large';
-    case 1:
-    default:
-      return 'medium';
-  }
-}, [fontSizeIndex]);
+const currentFontSize = FONT_SIZES[fontSizeIndex];
- className={`flex-1 overflow-y-auto p-6 ${currentFontSize} select-text readme-scrollbar relative`}
+ className={`flex-1 overflow-y-auto p-6 ${currentFontSize.value} select-text readme-scrollbar relative`}
- fontSize={getFontSizeType()}
+ fontSize={currentFontSize.type}
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/components/ReadmeModal.tsx` around lines 54 - 65, getFontSizeType
duplicates the index-to-size mapping already implied by FONT_SIZES and can
drift; replace the hardcoded switch in getFontSizeType to derive the type from
FONT_SIZES and fontSizeIndex (e.g., treat index 0 as 'small', index ===
FONT_SIZES.length - 1 as 'large', otherwise 'medium') so changes to FONT_SIZES
order/length automatically reflect in getFontSizeType; update references to
getFontSizeType accordingly.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@src/components/MarkdownRenderer.tsx`:
- Around line 769-779: getProseClass currently returns 'prose prose-xs
dark:prose-invert' for the 'small' fontSize, but Tailwind's typography plugin
doesn't include a prose-xs by default so the class will be ignored; either
change the small case to return a supported class (e.g., 'prose prose-sm
dark:prose-invert') or add a custom prose-xs variant in your Tailwind config and
rebuild; update the getProseClass function (and any tests/usage of fontSize)
accordingly to ensure small mode gets an actual prose size.

---

Outside diff comments:
In `@src/components/RepositoryEditModal.tsx`:
- Around line 666-667: The Tailwind class strings in RepositoryEditModal.tsx are
malformed (utility tokens concatenated without spaces) in the span wrapping the
FileText icon and two other similar span elements, which prevents Tailwind from
generating the light-mode styles; open RepositoryEditModal.tsx, locate the span
with the FileText component and the other two span elements that have
concatenated tokens in their className props, and fix each className by
inserting the missing spaces between utility tokens (preserving the intended
light/dark classes and order) so each Tailwind utility is a separate token and
styles are applied correctly.

---

Nitpick comments:
In `@src/components/ReadmeModal.tsx`:
- Around line 54-65: getFontSizeType duplicates the index-to-size mapping
already implied by FONT_SIZES and can drift; replace the hardcoded switch in
getFontSizeType to derive the type from FONT_SIZES and fontSizeIndex (e.g.,
treat index 0 as 'small', index === FONT_SIZES.length - 1 as 'large', otherwise
'medium') so changes to FONT_SIZES order/length automatically reflect in
getFontSizeType; update references to getFontSizeType accordingly.

In `@src/components/RepositoryCard.tsx`:
- Around line 879-898: The tooltip currently only opens on mouse hover; add
keyboard accessibility by making the truncated paragraph focusable and linking
it to the tooltip: add tabIndex={0} and onFocus={() => isTextTruncated &&
setShowTooltip(true)} and onBlur={() => setShowTooltip(false)} to the element
using descriptionRef (the <p> with ref={descriptionRef}), generate a stable
tooltip id (useId or state like tooltipId) and set
aria-describedby={isTextTruncated && showTooltip ? tooltipId : undefined} on
that <p>, give the tooltip div role="tooltip" and id={tooltipId}, and add an
onKeyDown handler on the <p> to close the tooltip on Escape by calling
setShowTooltip(false); keep existing mouse handlers and highlightSearchTerm
usage unchanged.
🪄 Autofix (Beta)

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: defaults

Review profile: CHILL

Plan: Pro

Run ID: 4877f256-4b54-4814-bc90-f241ff0a5b67

📥 Commits

Reviewing files that changed from the base of the PR and between f53535a and 0fceeeb.

📒 Files selected for processing (5)
  • src/components/MarkdownRenderer.tsx
  • src/components/ReadmeModal.tsx
  • src/components/RepositoryCard.tsx
  • src/components/RepositoryEditModal.tsx
  • src/index.css

Comment thread src/components/MarkdownRenderer.tsx
Adjust Tailwind typography classes in MarkdownRenderer: use 'prose prose-sm' for the 'small' fontSize instead of 'prose-xs', and remove the explicit 'prose-sm' for the medium/default case to fall back to the base 'prose' class. This normalizes sizing across fontSize options.
Fix stacking and improve the AI search tooltip UI and copy. Lowered SortByDropdown menu z-index to z-40 and added explicit z-indexes for the search input (z-40) and sort controls (z-30) to resolve overlay issues. Reworked the info tooltip: wider, responsive sizing, unified light/dark backgrounds and borders, improved text color/spacing, enabled word-wrapping, and adjusted the tooltip arrow styling/position. Also replaced the previous conditional AI copy with a single bilingual description explaining the multi-dimensional weighted search/ranking algorithm.
Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai Bot left a comment

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 the current code and only fix it if needed.

Inline comments:
In `@src/components/SearchBar.tsx`:
- Around line 903-908: The tooltip text in SearchBar.tsx currently always shows
the local weighted-algorithm copy; change the JSX that renders the translation
call (the t(...) block around '关于AI搜索' / 'About AI Search') to choose text based
on the actual runtime search mode used by the component (the same condition used
for AI selection at the runtime check around the search-mode logic and the
button title logic). Implement a small conditional (e.g., using
isAiSearchEnabled or the existing runtime condition used at lines ~565-585 and
the button title logic) to render an AI-mode description when AI search is
active and the weighted/local description when not, and ensure both strings are
passed through t(...) for translations (or extract to a helper like
getSearchTooltipText()).
🪄 Autofix (Beta)

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: defaults

Review profile: CHILL

Plan: Pro

Run ID: ca0d6971-9dc9-42cb-a383-f330b526190c

📥 Commits

Reviewing files that changed from the base of the PR and between bc1f547 and 47c3495.

📒 Files selected for processing (1)
  • src/components/SearchBar.tsx

Comment thread src/components/SearchBar.tsx Outdated
添加 hasHydrated 状态用于检测 store 是否完成水合
在 App 组件中添加加载状态以确保主题正确应用
更新搜索算法权重描述文案
根据activeAIConfig状态动态显示不同的搜索模式说明,当启用AI配置时显示语义搜索模式说明,否则显示本地智能排序说明
将加载状态的渲染逻辑移动到useEffect之后,使组件初始化逻辑更清晰
Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 3

🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@src/App.tsx`:
- Around line 75-84: The hydration gate early-return (checking hasHydrated) is
placed before several hooks causing a hooks count mismatch; move the hydration
check so that all hooks (including the useCallback and useMemo calls used in
App) are executed unconditionally on every render, then render the loading UI
conditionally after those hooks; also add a guard inside the second useEffect
(the effect that depends on hydration-related state) so it no-ops when
hasHydrated is false to avoid running hydration-only logic prematurely. Ensure
references to hasHydrated, the App component's useCallback/useMemo hooks, and
the second useEffect are updated accordingly.

In `@src/components/SearchBar.tsx`:
- Around line 906-913: The tooltip text for the non-AI path is inaccurate: when
activeAIConfig is falsy the search flow uses handleAISearch() which falls back
to performBasicTextSearch() and normal sort controls, not the weighted scoring
described. Update the conditional rendering in SearchBar (the branch using
activeAIConfig) so the false branch copy accurately describes the fallback
behavior (e.g., “Fallback: basic text search with default sorting and filters
via performBasicTextSearch and standard sort controls”) and remove or move the
weighted-scoring description to a place used only when the local weighted scorer
is actually applied.

In `@src/store/useAppStore.ts`:
- Around line 1498-1503: The onRehydrateStorage callback currently has the wrong
signature; change the implementation of onRehydrateStorage to accept the store
(state) and return a function with parameters (rehydratedState, error) so you
can detect IndexedDB rehydration failures — inside that returned callback call
state.setHasHydrated(true) in all cases (and optionally log error when error is
truthy) so the app (which relies on setHasHydrated) won't stay stuck loading;
update the function referenced as onRehydrateStorage and the use of
setHasHydrated accordingly.
🪄 Autofix (Beta)

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: defaults

Review profile: CHILL

Plan: Pro

Run ID: bc471678-55c3-46fc-9646-d354d4d60820

📥 Commits

Reviewing files that changed from the base of the PR and between 47c3495 and 2fc7158.

📒 Files selected for processing (3)
  • src/App.tsx
  • src/components/SearchBar.tsx
  • src/store/useAppStore.ts

Comment thread src/App.tsx Outdated
Comment thread src/components/SearchBar.tsx
Comment thread src/store/useAppStore.ts Outdated
SummerRay160 and others added 3 commits April 30, 2026 13:27
将加载状态的渲染逻辑移到认证检查之前,确保主题正确应用后再进行认证检查
Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com>
@AmintaCCCP
Copy link
Copy Markdown
Owner

能合了不?

@SummerRay160
Copy link
Copy Markdown
Contributor Author

可以在检查完成后合并
正在做MD翻译功能 这个PR可以先合并

@AmintaCCCP AmintaCCCP merged commit a570f13 into AmintaCCCP:main Apr 30, 2026
5 checks passed
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.

2 participants