Skip to content

fix(category): preserve manual category with lock during sync#49

Merged
AmintaCCCP merged 2 commits intomainfrom
fix/issue-39-40-category-lock
Mar 7, 2026
Merged

fix(category): preserve manual category with lock during sync#49
AmintaCCCP merged 2 commits intomainfrom
fix/issue-39-40-category-lock

Conversation

@AmintaCCCP
Copy link
Copy Markdown
Owner

@AmintaCCCP AmintaCCCP commented Mar 7, 2026

Summary

Implement category lock behavior to address #39 and #40:

  • Add category_locked field for repository metadata
  • In Repository Edit modal, add a category lock toggle with hover tooltip
  • When user manually changes category, lock is auto-enabled by default
  • User can manually disable lock later
  • Sync now preserves manual classification fields (custom_category, category_locked, and related manual edits) and will not reset them

Why

Users reported manual category changes being overwritten after sync, causing category confusion and instability.

Behavior

  • Manual edit category => lock auto ON
  • Lock ON => sync will not auto-change that repo category
  • User can toggle lock OFF anytime

Fixes #39
Relates #40

Summary by CodeRabbit

  • New Features
    • Category Locking: Users can lock repository categories to prevent automatic changes during sync; manually changing a category will auto-lock it to preserve the selection.
    • Enhanced Metadata Preservation: Sync now retains additional per-repository metadata (analysis status, custom description, tags, category lock state, and last-edited timestamps) so user-provided info is preserved.

@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai Bot commented Mar 7, 2026

📝 Walkthrough

Walkthrough

Adds a category lock feature: a new optional category_locked field on repositories, UI controls in the repository edit modal to toggle/auto-set the lock, and updated sync/merge logic to preserve this and other per-repo metadata during repository fetches.

Changes

Cohort / File(s) Summary
Type Definitions
src/types/index.ts
Added optional category_locked?: boolean to the Repository interface.
Sync / Merge Logic
src/components/Header.tsx
Merge/update logic now preserves per-repo metadata from existing repos into fetched repos: analysis_failed, custom_description, custom_tags, custom_category, category_locked, and last_edited.
Edit Modal UI & Persistence
src/components/RepositoryEditModal.tsx
Added category lock state to form data, Lock/Unlock icons and switch in the modal, initialization from repository.category_locked, auto-enable lock when category changes, persist category_locked on save, and reset lock state on modal close.

Sequence Diagram(s)

sequenceDiagram
    participant User
    participant UI as RepositoryEditModal
    participant App as ClientState
    participant Sync as HeaderSync
    participant Store as RepoStore

    User->>UI: Open edit modal (select repo)
    UI->>App: load repo data (includes category_locked)
    App-->>UI: repo + category_locked
    User->>UI: change category (or toggle lock)
    UI->>App: save form (category, category_locked)
    App->>Store: persist repo update
    Store-->>App: ack
    Note over Sync, Store: Later: fetch remote repos
    Sync->>Store: fetch new repo list
    Store->>App: return existing repos
    Sync->>App: merge fetched repos with existing
    alt existing repo present
        App-->>Sync: preserve metadata fields (`analysis_failed`, `custom_description`, `custom_tags`, `custom_category`, `category_locked`, `last_edited`)
    end
    Sync->>Store: write merged repos
    Store-->>Sync: ack
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

Poem

🐰 I nudged a tiny lock into place,
So categories stay put, calm and ace.
When I hop and I tag, it won't roam,
Pinned snug like a carrot in home. 🥕🔒

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title 'fix(category): preserve manual category with lock during sync' clearly summarizes the main objective of the pull request: implementing a category lock mechanism to prevent manual category changes from being overwritten during synchronization.
Linked Issues check ✅ Passed The pull request successfully addresses issue #39 by implementing a category lock mechanism that preserves manual category edits across synchronizations. The changes add category_locked field, UI toggle, auto-lock on manual change, and preserve locked categories during sync.
Out of Scope Changes check ✅ Passed All changes are directly related to implementing the category lock feature for issue #39. The modifications to Header.tsx, RepositoryEditModal.tsx, and types/index.ts all serve the primary objective of preserving manual category edits.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.

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

✨ Finishing Touches
  • 📝 Generate docstrings (stacked PR)
  • 📝 Generate docstrings (commit on current branch)
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch fix/issue-39-40-category-lock

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

Caution

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

⚠️ Outside diff range comments (1)
src/components/Header.tsx (1)

41-62: ⚠️ Potential issue | 🟠 Major

Preserve locked/manual metadata on the backend sync path too.

This merge only runs in Header.handleSync(). src/services/autoSync.ts:48-110 still calls state.setRepositories(reposResult.value.repositories) with raw backend objects from src/services/backendAdapter.ts:219-227, so a later backend sync can drop category_locked and the other preserved manual fields again. Please move this merge into a shared helper/store action and apply it before every setRepositories(...).

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/components/Header.tsx` around lines 41 - 62, The merging logic that
preserves manual/locked metadata (currently in Header.handleSync() producing
mergedRepositories and calling setRepositories) must be moved into a shared
helper or store action so it runs before every repository state update; create a
function (e.g., mergeRepositoriesPreservingManualFields(existingRepos,
newRepos)) that applies the same field preservation (ai_summary, ai_tags,
ai_platforms, analyzed_at, analysis_failed, custom_description, custom_tags,
custom_category, category_locked, last_edited) and call it wherever repositories
are set (replace direct calls to
state.setRepositories(reposResult.value.repositories) in autoSync
(src/services/autoSync.ts) and the backendAdapter path that returns raw objects)
so setRepositories always receives merged results. Ensure Header.handleSync()
uses the shared helper instead of inline merging and update any tests or callers
to use the helper prior to calling state.setRepositories.
🤖 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/RepositoryEditModal.tsx`:
- Around line 225-236: The checkbox input for the category lock (bound to
formData.categoryLocked and updated by setFormData) lacks an accessible name;
add an id to the input (e.g. category-lock-checkbox) and connect the existing
<label> to it via htmlFor, or alternatively add aria-labelledby/aria-label that
references the visible “Category Lock” text so screen readers properly announce
the control; ensure the id/label pair is unique and the onChange handler and
className remain unchanged.
- Around line 89-98: The save currently forces category_locked to true when
detecting a category change (categoryChanged), which overrides the user's
toggle; update the save logic in handleSave so it respects the current toggle
value instead of unconditionally forcing true—replace the category_locked
assignment in updatedRepo (currently using categoryChanged ? true :
formData.categoryLocked) with one that simply uses formData.categoryLocked (or
otherwise honor the toggle state), or alternatively implement UI behavior that
immediately forces/disables the toggle when originalCategory vs
formData.category changes so the saved value and displayed toggle can't diverge.

---

Outside diff comments:
In `@src/components/Header.tsx`:
- Around line 41-62: The merging logic that preserves manual/locked metadata
(currently in Header.handleSync() producing mergedRepositories and calling
setRepositories) must be moved into a shared helper or store action so it runs
before every repository state update; create a function (e.g.,
mergeRepositoriesPreservingManualFields(existingRepos, newRepos)) that applies
the same field preservation (ai_summary, ai_tags, ai_platforms, analyzed_at,
analysis_failed, custom_description, custom_tags, custom_category,
category_locked, last_edited) and call it wherever repositories are set (replace
direct calls to state.setRepositories(reposResult.value.repositories) in
autoSync (src/services/autoSync.ts) and the backendAdapter path that returns raw
objects) so setRepositories always receives merged results. Ensure
Header.handleSync() uses the shared helper instead of inline merging and update
any tests or callers to use the helper prior to calling state.setRepositories.

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: b4007c51-f4c2-4e67-8bcc-a4b19d5f3a0e

📥 Commits

Reviewing files that changed from the base of the PR and between 361af59 and 2aebc14.

📒 Files selected for processing (3)
  • src/components/Header.tsx
  • src/components/RepositoryEditModal.tsx
  • src/types/index.ts

Comment on lines +89 to +98
const originalCategory = getCurrentCategory(repository);
const categoryChanged = formData.category !== originalCategory;

const updatedRepo = {
...repository,
custom_description: formData.description !== repository.description ? formData.description : undefined,
custom_tags: formData.tags.length > 0 ? formData.tags : undefined,
custom_category: formData.category ? formData.category : undefined,
// 手动修改分类时,默认自动锁定;用户仍可手动取消
category_locked: categoryChanged ? true : formData.categoryLocked,
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.

⚠️ Potential issue | 🟠 Major

The save path can silently override the switch state.

When the category changes, Line 98 always persists category_locked: true, even if the user turned the toggle off in the same dialog. That leaves the control showing one state and saving another. Either force the toggle on/disable it as soon as the category changes, or make handleSave() respect the current toggle value.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/components/RepositoryEditModal.tsx` around lines 89 - 98, The save
currently forces category_locked to true when detecting a category change
(categoryChanged), which overrides the user's toggle; update the save logic in
handleSave so it respects the current toggle value instead of unconditionally
forcing true—replace the category_locked assignment in updatedRepo (currently
using categoryChanged ? true : formData.categoryLocked) with one that simply
uses formData.categoryLocked (or otherwise honor the toggle state), or
alternatively implement UI behavior that immediately forces/disables the toggle
when originalCategory vs formData.category changes so the saved value and
displayed toggle can't diverge.

Comment on lines +225 to +236
<label
className="inline-flex items-center cursor-pointer"
title={t(
'开启后,同步时不会自动修改该仓库分类。手动修改分类会自动开启此开关。',
'When enabled, sync will not auto-change this repository category. Manually changing category will enable this lock by default.'
)}
>
<input
type="checkbox"
checked={formData.categoryLocked}
onChange={(e) => setFormData(prev => ({ ...prev, categoryLocked: e.target.checked }))}
className="sr-only peer"
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.

⚠️ Potential issue | 🟠 Major

Give the lock switch an accessible name.

The visible “Category Lock” text is outside the <label>, and the checkbox itself only has a tooltip. Screen readers will treat this as an unlabeled control. Please associate the text with the input via htmlFor/id or aria-labelledby/aria-label.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/components/RepositoryEditModal.tsx` around lines 225 - 236, The checkbox
input for the category lock (bound to formData.categoryLocked and updated by
setFormData) lacks an accessible name; add an id to the input (e.g.
category-lock-checkbox) and connect the existing <label> to it via htmlFor, or
alternatively add aria-labelledby/aria-label that references the visible
“Category Lock” text so screen readers properly announce the control; ensure the
id/label pair is unique and the onChange handler and className remain unchanged.

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

♻️ Duplicate comments (2)
src/components/RepositoryEditModal.tsx (2)

225-241: ⚠️ Potential issue | 🟠 Major

Give the lock switch an accessible name.

The visible "Category Lock" text (lines 221-223) is outside the <label> that wraps the checkbox. The checkbox itself only has a tooltip via the label's title attribute. Screen readers will treat this as an unlabeled control.

Associate the text with the input via htmlFor/id or add aria-label to the checkbox.

♻️ Proposed fix using aria-label
              <input
                type="checkbox"
                checked={formData.categoryLocked}
                onChange={(e) => setFormData(prev => ({ ...prev, categoryLocked: e.target.checked }))}
                className="sr-only peer"
+               aria-label={t('分类锁定', 'Category Lock')}
              />
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/components/RepositoryEditModal.tsx` around lines 225 - 241, The checkbox
lacks an accessible name; update the input in the RepositoryEditModal so screen
readers can associate the visible "Category Lock" text with the control—either
add a stable id on the input and move or add an associated <label
htmlFor="{id}"> (or add aria-labelledby referencing the visible text element's
id) or provide a clear aria-label on the input; ensure this touches the checkbox
input that reads formData.categoryLocked and its onChange handler (setFormData)
so the visible label and the input are programmatically linked for
accessibility.

89-98: ⚠️ Potential issue | 🟠 Major

The save path can silently override the switch state.

When the category changes, line 98 always persists category_locked: true, even if the user turned the toggle off in the same dialog session. This creates a state mismatch where the toggle shows one value but a different value is saved.

Consider either:

  1. Forcing the toggle ON and disabling it when the category changes (so UI matches saved value)
  2. Respecting formData.categoryLocked unconditionally: category_locked: formData.categoryLocked
♻️ Option 2: Always respect the toggle state
-      category_locked: categoryChanged ? true : formData.categoryLocked,
+      category_locked: formData.categoryLocked,

And auto-enable the toggle when category changes in the onChange handler of the category select (lines 197-198).

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/components/RepositoryEditModal.tsx` around lines 89 - 98, The save
currently forces category_locked to true when categoryChanged (computed from
getCurrentCategory and formData.category) causing the saved state to disagree
with the UI toggle; change updatedRepo so category_locked is set from
formData.categoryLocked (i.e. respect the toggle) and, in the category select
onChange handler (the handler that updates formData.category), detect when the
new category differs from getCurrentCategory(repository) and set
formData.categoryLocked = true there (and optionally set the toggle UI to
disabled when the category is different) so the toggle is auto-enabled on manual
category change and the saved value matches what the user sees.
🤖 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/RepositoryEditModal.tsx`:
- Around line 238-240: The inner knob div is a child of the track div so the
Tailwind peer-checked:translate-x-full never matches; either move the knob
element out so it's a direct sibling of the element with class "peer" or convert
the knob to an after: pseudo-element on the track div and use
peer-checked:after:translate-x-full (update the track div's classes like
peer-checked:after:translate-x-full, after:... sizing and transition). Update
the JSX around the checkbox input/track so the element with "peer" and the
visual knob (now a sibling or an after:) are siblings and ensure transitions
remain (e.g., include transition-transform on the after/knob and set initial
translate/position via after: classes).
- Around line 97-98: The AI batch analysis in analyzeRepository
(RepositoryList.tsx) currently overwrites ai_summary, ai_tags, and ai_platforms
without checking the category_locked flag set in RepositoryEditModal
(category_locked), so update analyzeRepository to read the repository's
category_locked boolean and, if true, skip updating the category-related outputs
(or preserve existing ai_summary/ai_tags/ai_platforms) instead of overwriting
them; locate the analyzeRepository function and add a guard that checks
repo.category_locked before assigning to ai_summary, ai_tags, ai_platforms to
ensure locked repositories are not re-analyzed.

---

Duplicate comments:
In `@src/components/RepositoryEditModal.tsx`:
- Around line 225-241: The checkbox lacks an accessible name; update the input
in the RepositoryEditModal so screen readers can associate the visible "Category
Lock" text with the control—either add a stable id on the input and move or add
an associated <label htmlFor="{id}"> (or add aria-labelledby referencing the
visible text element's id) or provide a clear aria-label on the input; ensure
this touches the checkbox input that reads formData.categoryLocked and its
onChange handler (setFormData) so the visible label and the input are
programmatically linked for accessibility.
- Around line 89-98: The save currently forces category_locked to true when
categoryChanged (computed from getCurrentCategory and formData.category) causing
the saved state to disagree with the UI toggle; change updatedRepo so
category_locked is set from formData.categoryLocked (i.e. respect the toggle)
and, in the category select onChange handler (the handler that updates
formData.category), detect when the new category differs from
getCurrentCategory(repository) and set formData.categoryLocked = true there (and
optionally set the toggle UI to disabled when the category is different) so the
toggle is auto-enabled on manual category change and the saved value matches
what the user sees.

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 46bc7755-b3b3-4621-aeeb-992125380e6c

📥 Commits

Reviewing files that changed from the base of the PR and between 2aebc14 and f297097.

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

Comment on lines +97 to +98
// 手动修改分类时,默认自动锁定;用户仍可手动取消
category_locked: categoryChanged ? true : formData.categoryLocked,
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.

⚠️ Potential issue | 🟠 Major

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
# Check if category_locked is consulted before AI analysis overwrites fields
rg -n -A5 "analyzeRepository" --type ts | head -50

Repository: AmintaCCCP/GithubStarsManager

Length of output: 2256


🏁 Script executed:

#!/bin/bash
# Find all places that set ai_summary, ai_tags to verify they respect the lock
rg -n "ai_summary.*=" --type ts

Repository: AmintaCCCP/GithubStarsManager

Length of output: 138


🏁 Script executed:

cat -n src/components/RepositoryList.tsx | sed -n '176,210p'

Repository: AmintaCCCP/GithubStarsManager

Length of output: 1407


🏁 Script executed:

# Also check if category_locked is referenced anywhere in RepositoryList.tsx
rg -n "category_locked" src/components/RepositoryList.tsx

Repository: AmintaCCCP/GithubStarsManager

Length of output: 55


🏁 Script executed:

# Search for all references to category_locked across the codebase
rg -n "category_locked" --type ts --type tsx

Repository: AmintaCCCP/GithubStarsManager

Length of output: 100


🏁 Script executed:

# Check the Repository type definition to understand category_locked field
rg -n "category_locked" --type ts --type tsx -B 2 -A 2

Repository: AmintaCCCP/GithubStarsManager

Length of output: 100


🏁 Script executed:

# Search for all references to category_locked across the codebase
rg -n "category_locked"

Repository: AmintaCCCP/GithubStarsManager

Length of output: 440


🏁 Script executed:

# Check the Repository type definition
fd ".*Repository.*" -e ts -e tsx | head -20

Repository: AmintaCCCP/GithubStarsManager

Length of output: 179


🏁 Script executed:

# Check the comment/context around category_locked in types
cat -n src/types/index.ts | sed -n '25,35p'

Repository: AmintaCCCP/GithubStarsManager

Length of output: 422


🏁 Script executed:

# Check Header.tsx to see how category_locked is used there
cat -n src/components/Header.tsx | sed -n '50,60p'

Repository: AmintaCCCP/GithubStarsManager

Length of output: 573


🏁 Script executed:

# Search for where category_locked is actually checked (used in conditionals)
rg -n "category_locked" -B 2 -A 2 --context 3

Repository: AmintaCCCP/GithubStarsManager

Length of output: 2117


🏁 Script executed:

# Check if there's any sync logic that respects category_locked
rg -n "sync" -A 5 -B 5 src/components/RepositoryList.tsx | head -60

Repository: AmintaCCCP/GithubStarsManager

Length of output: 1394


🏁 Script executed:

# Check the entire RepositoryList.tsx to see the broader context of the batch AI analysis
cat -n src/components/RepositoryList.tsx | sed -n '1,50p'

Repository: AmintaCCCP/GithubStarsManager

Length of output: 1949


🏁 Script executed:

# Check if category_locked is checked anywhere in sync operations
rg -n "sync" --context 5 src/components/Header.tsx | head -80

Repository: AmintaCCCP/GithubStarsManager

Length of output: 949


🏁 Script executed:

# Look for where the sync actually happens and if it checks category_locked
rg -n "updateRepository\|setRepositories" src/components/Header.tsx -B 3 -A 3 | head -50

Repository: AmintaCCCP/GithubStarsManager

Length of output: 55


🏁 Script executed:

# Look at the full handleSync function in Header.tsx
cat -n src/components/Header.tsx | sed -n '25,100p'

Repository: AmintaCCCP/GithubStarsManager

Length of output: 3166


🏁 Script executed:

# Check if category_locked is checked anywhere during repository updates or sync
rg -n "category_locked" -B 5 -A 5 src/components/Header.tsx

Repository: AmintaCCCP/GithubStarsManager

Length of output: 529


Add category_locked check before AI batch analysis updates.

The category_locked flag (defined in src/types/index.ts as preventing automatic category changes) is not consulted during AI batch analysis in RepositoryList.tsx. When analyzeRepository runs at lines 198-210, it overwrites ai_summary, ai_tags, and ai_platforms without checking if the category is locked. If category_locked should also prevent re-analysis of locked repositories, add a guard condition to skip or preserve fields for locked entries.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/components/RepositoryEditModal.tsx` around lines 97 - 98, The AI batch
analysis in analyzeRepository (RepositoryList.tsx) currently overwrites
ai_summary, ai_tags, and ai_platforms without checking the category_locked flag
set in RepositoryEditModal (category_locked), so update analyzeRepository to
read the repository's category_locked boolean and, if true, skip updating the
category-related outputs (or preserve existing ai_summary/ai_tags/ai_platforms)
instead of overwriting them; locate the analyzeRepository function and add a
guard that checks repo.category_locked before assigning to ai_summary, ai_tags,
ai_platforms to ensure locked repositories are not re-analyzed.

Comment on lines +238 to +240
<div className="relative w-10 h-6 bg-gray-200 peer-focus:outline-none peer-focus:ring-2 peer-focus:ring-blue-500 dark:peer-focus:ring-blue-800 rounded-full peer dark:bg-gray-700 peer-checked:bg-blue-600">
<div className="absolute top-[2px] left-[2px] bg-white border-gray-300 border rounded-full h-5 w-5 transition-transform peer-checked:translate-x-full"></div>
</div>
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.

⚠️ Potential issue | 🟡 Minor

Toggle knob won't animate — peer-checked: on nested element.

Tailwind's peer-* variants use the CSS ~ sibling combinator, which only matches elements that are direct siblings of the .peer element. The inner knob div (line 239) is a child of a sibling, not a sibling itself, so peer-checked:translate-x-full will never apply. The track color change on line 238 will work (it's a sibling), but the knob won't slide.

♻️ Fix using `after:` pseudo-element pattern
-              <div className="relative w-10 h-6 bg-gray-200 peer-focus:outline-none peer-focus:ring-2 peer-focus:ring-blue-500 dark:peer-focus:ring-blue-800 rounded-full peer dark:bg-gray-700 peer-checked:bg-blue-600">
-                <div className="absolute top-[2px] left-[2px] bg-white border-gray-300 border rounded-full h-5 w-5 transition-transform peer-checked:translate-x-full"></div>
-              </div>
+              <div className="relative w-10 h-6 bg-gray-200 peer-focus:outline-none peer-focus:ring-2 peer-focus:ring-blue-500 dark:peer-focus:ring-blue-800 rounded-full dark:bg-gray-700 peer-checked:bg-blue-600 after:content-[''] after:absolute after:top-[2px] after:left-[2px] after:bg-white after:border-gray-300 after:border after:rounded-full after:h-5 after:w-5 after:transition-transform peer-checked:after:translate-x-full"></div>

This uses the after: pseudo-element for the knob, allowing peer-checked:after:translate-x-full to work correctly since the parent div is a sibling of the peer.

📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
<div className="relative w-10 h-6 bg-gray-200 peer-focus:outline-none peer-focus:ring-2 peer-focus:ring-blue-500 dark:peer-focus:ring-blue-800 rounded-full peer dark:bg-gray-700 peer-checked:bg-blue-600">
<div className="absolute top-[2px] left-[2px] bg-white border-gray-300 border rounded-full h-5 w-5 transition-transform peer-checked:translate-x-full"></div>
</div>
<div className="relative w-10 h-6 bg-gray-200 peer-focus:outline-none peer-focus:ring-2 peer-focus:ring-blue-500 dark:peer-focus:ring-blue-800 rounded-full dark:bg-gray-700 peer-checked:bg-blue-600 after:content-[''] after:absolute after:top-[2px] after:left-[2px] after:bg-white after:border-gray-300 after:border after:rounded-full after:h-5 after:w-5 after:transition-transform peer-checked:after:translate-x-full"></div>
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/components/RepositoryEditModal.tsx` around lines 238 - 240, The inner
knob div is a child of the track div so the Tailwind
peer-checked:translate-x-full never matches; either move the knob element out so
it's a direct sibling of the element with class "peer" or convert the knob to an
after: pseudo-element on the track div and use
peer-checked:after:translate-x-full (update the track div's classes like
peer-checked:after:translate-x-full, after:... sizing and transition). Update
the JSX around the checkbox input/track so the element with "peer" and the
visual knob (now a sibling or an after:) are siblings and ensure transitions
remain (e.g., include transition-transform on the after/knob and set initial
translate/position via after: classes).

@AmintaCCCP AmintaCCCP merged commit a85181b into main Mar 7, 2026
5 checks passed
@AmintaCCCP AmintaCCCP deleted the fix/issue-39-40-category-lock branch March 7, 2026 10:07
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.

【Bug】分类修改不生效

1 participant