Conversation
📝 WalkthroughWalkthroughThis pull request modifies the key resolution logic in the Tree component to change the priority for determining item expansion keys. A new helper function Estimated code review effort🎯 2 (Simple) | ⏱️ ~12 minutes 🚥 Pre-merge checks | ✅ 3✅ Passed checks (3 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches🧪 Generate unit tests (beta)
📝 Coding Plan
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. Comment |
There was a problem hiding this comment.
🧹 Nitpick comments (2)
test/components/Tree.spec.ts (1)
117-125: Variable shadowing:itemsshadows outer scope.The local
items(line 117) andupdatedItems(line 123) shadow the test file'sitemsfixture at line 13. While scoping is correct, renaming improves clarity:♻️ Suggested rename
- const items = wrapper.findAll('[role="treeitem"]') - const nestedReferences = items.find(item => item.text() === 'references' && item.attributes('aria-level') === '2') + const treeItems = wrapper.findAll('[role="treeitem"]') + const nestedReferences = treeItems.find(item => item.text() === 'references' && item.attributes('aria-level') === '2') expect(nestedReferences).toBeDefined() await nestedReferences!.trigger('click') - const updatedItems = wrapper.findAll('[role="treeitem"]') - const rootReferences = updatedItems.find(item => item.text() === 'references' && item.attributes('aria-level') === '1') - const reopenedNestedReferences = updatedItems.find(item => item.text() === 'references' && item.attributes('aria-level') === '2') + const updatedTreeItems = wrapper.findAll('[role="treeitem"]') + const rootReferences = updatedTreeItems.find(item => item.text() === 'references' && item.attributes('aria-level') === '1') + const reopenedNestedReferences = updatedTreeItems.find(item => item.text() === 'references' && item.attributes('aria-level') === '2')🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@test/components/Tree.spec.ts` around lines 117 - 125, Rename the local test variables that shadow the file-level fixture to avoid confusion: change the local const items and const updatedItems in the test to distinct names (e.g., foundItems and updatedFoundItems) and update subsequent references nestedReferences, rootReferences, and reopenedNestedReferences to use those new names; ensure you only rename the local bindings used around the wrapper.findAll('[role="treeitem"]') calls and the subsequent .find(...) lookups so the top-level items fixture (defined at line 13) is no longer shadowed.src/runtime/components/Tree.vue (1)
238-242: Note: Empty string fromgetKeytriggers fallback.The
||operator means if a customgetKeyreturns""(empty string), the logic falls through togetItemValueKey. This is likely the desired safety behavior but worth noting for documentation—if a user truly wants an empty-string key, this won't work.If strict custom key handling is ever needed:
💡 Alternative using nullish coalescing
function getItemKey<Item extends T[number]>(item: Item): string { - return props.getKey - ? props.getKey(item) || getItemValueKey(item) || getItemLabel(item) + return props.getKey + ? (props.getKey(item) ?? getItemValueKey(item) ?? getItemLabel(item)) || getItemLabel(item) : getItemValueKey(item) || getItemLabel(item) }Given that empty-string keys are an unlikely edge case and the current behavior provides safer defaults, this is fine as-is.
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@src/runtime/components/Tree.vue` around lines 238 - 242, The current getItemKey function uses || which treats an empty string from props.getKey as falsy and falls back to getItemValueKey/getItemLabel; if you need to preserve explicit empty-string keys, change getItemKey to use nullish coalescing for the custom key path (i.e., treat only null/undefined as missing) so props.getKey(item) ?? getItemValueKey(item) ?? getItemLabel(item) is used; update the logic in the getItemKey function (and ensure getKey, getItemValueKey, getItemLabel references remain correct) and add a brief comment explaining why ?? is used.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Nitpick comments:
In `@src/runtime/components/Tree.vue`:
- Around line 238-242: The current getItemKey function uses || which treats an
empty string from props.getKey as falsy and falls back to
getItemValueKey/getItemLabel; if you need to preserve explicit empty-string
keys, change getItemKey to use nullish coalescing for the custom key path (i.e.,
treat only null/undefined as missing) so props.getKey(item) ??
getItemValueKey(item) ?? getItemLabel(item) is used; update the logic in the
getItemKey function (and ensure getKey, getItemValueKey, getItemLabel references
remain correct) and add a brief comment explaining why ?? is used.
In `@test/components/Tree.spec.ts`:
- Around line 117-125: Rename the local test variables that shadow the
file-level fixture to avoid confusion: change the local const items and const
updatedItems in the test to distinct names (e.g., foundItems and
updatedFoundItems) and update subsequent references nestedReferences,
rootReferences, and reopenedNestedReferences to use those new names; ensure you
only rename the local bindings used around the
wrapper.findAll('[role="treeitem"]') calls and the subsequent .find(...) lookups
so the top-level items fixture (defined at line 13) is no longer shadowed.
ℹ️ Review info
⚙️ Run configuration
Configuration used: Organization UI
Review profile: CHILL
Plan: Pro
Run ID: 7e31d0ad-03dc-4cae-bc83-2fadff618713
📒 Files selected for processing (2)
src/runtime/components/Tree.vuetest/components/Tree.spec.ts
commit: |
|
@sandros94 Do you remember why we chose not to have |
TBH no, and checking when it was first being implemented I see that it was a period were I was not very active, so might be a simple oversight 😰 |
Without a custom
getKeyprop,getItemKey()defaults to the item's label. Items with the same label at different nesting levels (e.g. two folders named "references") share expansion/selection state.The fix I implemented is a to build a
WeakMapmapping each item to a unique index-based path (e.g.0,1-0,1-0-0). UsestoRaw()to handle Vue reactive proxies. Backward-compatible: users withgetKeyprop are unaffected.