Skip to content

Conversation

@xfl12345
Copy link

@xfl12345 xfl12345 commented Oct 15, 2025

Summary by CodeRabbit

  • Bug Fixes

    • Collapsible text sections now open and close more reliably.
    • Icon rotation and content visibility stay in sync with the section’s state.
    • Default open/closed behavior is more consistent across renders.
  • Refactor

    • Updated internal state handling for collapsible text to improve consistency and pave the way for future enhancements.

@coderabbitai
Copy link

coderabbitai bot commented Oct 15, 2025

Walkthrough

Replaced the defaultOpen prop with a model-backed open state. Added internal openInternal ref and an open computed that proxies to model.open when available. Updated template bindings and click handler to use open. Removed all references to opened and defaultOpen.

Changes

Cohort / File(s) Summary
Collapsible Text component state modelization
packages/components/src/bubble/renderers/collapsible-text.vue
- Removed prop defaultOpen.
- Added defineModel<{ open?: boolean }> with empty default.
- Introduced openInternal (ref) and open (computed getter/setter) delegating to model when present.
- Updated template bindings (icon rotation, visibility, click toggle) to use open.
- Removed all opened references.

Sequence Diagram(s)

sequenceDiagram
  autonumber
  participant P as Parent
  participant C as CollapsibleText
  participant M as model.open (optional)
  participant L as openInternal (local)

  Note over C: Component mounts

  alt Model provided
    P->>C: Bind v-model:open
    C->>M: Read model.open via computed getter
    P->>C: User click toggles
    C->>M: Setter updates model.open
    M-->>P: Parent reacts to change
  else No model provided
    C->>L: Read/write openInternal via computed
    P->>C: User click toggles
    C->>L: Setter updates openInternal
  end

  C->>C: UI reflects `open` (icon rotate, content visibility)
Loading

Estimated code review effort

🎯 2 (Simple) | ⏱️ ~10 minutes

Poem

A bunny flips a toggle, neat and clean,
No prop to guard the fold—new state unseen.
If parent speaks, I heed its open call;
If not, I keep a secret in my burrowed wall.
Click—whiskers twitch—the panels preen.

Pre-merge checks and finishing touches

✅ Passed checks (3 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title Check ✅ Passed The title succinctly describes the primary refactor by indicating that the collapsible-text component’s fold state is now reactive, includes the relevant scope, and uses concise, clear phrasing without extraneous detail.
Docstring Coverage ✅ Passed No functions found in the changes. Docstring coverage check skipped.
✨ Finishing touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment

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

@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: 0

🧹 Nitpick comments (2)
packages/components/src/bubble/renderers/collapsible-text.vue (2)

5-9: Consider simplifying the model pattern.

The current pattern uses defineModel<{ open?: boolean }>() with a default empty object, which requires additional logic to check if model.value.open is set. This adds complexity compared to the more idiomatic Vue 3 approach of using defineModel<boolean>('open', { default: false }) with v-model:open.

If you prefer the current object-based model pattern, consider this alternative that's clearer:

-const model = defineModel<{ open?: boolean }>({
-  default() {
-    return {}
-  },
-})
+const model = defineModel<boolean>('open')

Then simplify the state management:

 const openInternal = ref(false)
-const modelOpenIsSet = computed<boolean>(() => model.value && model.value.open !== void 0)
 const open = computed<boolean>({
   get() {
-    return modelOpenIsSet.value ? model.value.open! : openInternal.value
+    return model.value ?? openInternal.value
   },
   set(value) {
-    if (modelOpenIsSet.value) {
-      model.value.open = value
-    } else {
-      openInternal.value = value
-    }
+    model.value = value
   },
 })

This approach:

  • Uses the standard v-model:open syntax
  • Eliminates the need for modelOpenIsSet helper
  • Removes the non-null assertion
  • Simplifies the mental model for users

16-29: No defaultOpen usages found—review state transition logic
Verified that the defaultOpen prop has been fully removed. The open getter still uses a non-null assertion (model.value.open!) and will flip from internal to model-controlled state if an open property is added at runtime, which can be surprising. Consider replacing it with

get() {
  return model.value.open ?? openInternal.value
}

and documenting this behavior.

📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between d1a6268 and 1488805.

📒 Files selected for processing (1)
  • packages/components/src/bubble/renderers/collapsible-text.vue (1 hunks)
🔇 Additional comments (2)
packages/components/src/bubble/renderers/collapsible-text.vue (2)

36-36: LGTM!

The template binding correctly uses the open computed property for both the rotation class and click handler.


39-39: LGTM!

The v-show directive correctly uses the open computed property to control content visibility.

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