-
Notifications
You must be signed in to change notification settings - Fork 178
feat(MentionSender, Sender): add openHeader prop for controlling head… #340
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Conversation
WalkthroughAdds a new openHeader prop with v-model support to Sender and MentionSender for controlling header visibility; emits update:openHeader. Demos, docs (EN/ZH), and stories are updated to use reactive binding instead of imperative methods. Deprecates openHeader()/closeHeader() methods. Removes two global component typings. Adds a new .gitignore pattern. Changes
Sequence Diagram(s)sequenceDiagram
autonumber
actor User
participant Parent as Parent (Demo/Story)
participant Comp as Sender / MentionSender
Note over Parent,Comp: Two-way binding with v-model:openHeader
User->>Parent: Click toggle
Parent->>Parent: openHeader = !openHeader
Parent->>Comp: prop openHeader updated
Comp->>Comp: headerOpenState syncs internalHeaderOpen
Comp-->>Parent: emit update:openHeader(openHeader)
Note right of Comp: Header shown/hidden based on headerOpenState
sequenceDiagram
autonumber
participant Parent
participant Comp as Sender / MentionSender
rect rgba(255,235,205,0.4)
Note over Parent,Comp: Deprecated path (still supported)
Parent->>Comp: call openHeader() / closeHeader()
Comp->>Comp: headerOpenState = true/false
Comp-->>Parent: emit update:openHeader(value)
end
Estimated code review effort🎯 3 (Moderate) | ⏱️ ~25 minutes Possibly related PRs
Poem
Tip 👮 Agentic pre-merge checks are now available in preview!Pro plan users can now enable pre-merge checks in their settings to enforce checklists before merging PRs.
Example: reviews:
pre_merge_checks:
custom_checks:
- name: "Undocumented Breaking Changes"
mode: "warning"
instructions: |
Pass/fail criteria: All breaking changes to public APIs, CLI flags, environment variables, configuration keys, database schemas, or HTTP/GraphQL endpoints must be documented in the "Breaking Change" section of the PR description and in CHANGELOG.md. Exclude purely internal or private changes (e.g., code not exported from package entry points or explicitly marked as internal).Please share your feedback with us on this Discord post. ✨ Finishing Touches
🧪 Generate 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. Comment |
|
Generate unit tests |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 5
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (3)
packages/core/src/stories/Sender/CustomSolt.vue (1)
175-177: Missing icon import for (compile error).
<Link />is used but not imported.-import { CircleClose, Delete, Position } from '@element-plus/icons-vue'; +import { CircleClose, Delete, Position, Link } from '@element-plus/icons-vue';packages/core/src/stories/MentionSender/CustomSolt.vue (1)
179-186: Missing icon import: is used but not imported.This will fail at compile time. Import it from @element-plus/icons-vue.
-import { CircleClose, Delete, Position } from '@element-plus/icons-vue'; +import { CircleClose, Delete, Position, Link } from '@element-plus/icons-vue';packages/core/src/components/Sender/index.vue (1)
1-585: Fix style lint errors in Sender component
There are 19 antfu/if-newline and style/brace-style violations in packages/core/src/components/Sender/index.vue; runnpx eslint --fix packages/core/src/components/Sender/index.vueor manually adjust newline-after-
ifand brace placements to satisfy CI.
🧹 Nitpick comments (21)
.gitignore (1)
50-50: Clarify intent of .cunzhi ignore.*If you intend to ignore only directories, add a trailing slash. If both files and dirs are intended, this is fine.
Optional tweak:
-.cunzhi* +.cunzhi*/packages/core/src/components/MentionSender/index.vue (4)
100-123: Emit only on actual state change to avoid redundant updates.Guard the setter to prevent no-op emits and possible parent churn.
Apply:
const headerOpenState = computed({ get() { return internalHeaderOpen.value; }, set(value) { - if (props.readOnly || props.disabled) return; - - internalHeaderOpen.value = value; - // 始终触发更新事件,让外部可以监听状态变化 - emits('update:openHeader', value); + if (props.readOnly || props.disabled) return; + if (internalHeaderOpen.value === value) return; + internalHeaderOpen.value = value; + emits('update:openHeader', value); } });
153-188: Usee.key === 'Enter'instead of deprecatedkeyCode.
KeyboardEvent.keyCodeis deprecated; preferkey === 'Enter'. Also fix brace style at} else {to satisfy lint.Apply:
- if ('webkitSpeechRecognition' in window) { + if ('webkitSpeechRecognition' in window) { ... - recognition.value.start(); - } else { + recognition.value.start(); + } + else { console.error('浏览器不支持 Web Speech API'); }And later:
- if (e.keyCode === 13) { + if (e.key === 'Enter') { e.preventDefault(); if (props.submitType === 'enter') { _isComKeyDown ? _resetSelectionRange() : submit(); - } else { + } + else { _isComKeyDown ? submit() : _resetSelectionRange(); } }
52-59: Fix lint: newline-after-if and brace style.ESLint errors (antfu/if-newline, style/brace-style) are from single-line
ifreturns and} else {on the same line. Expand to multi-line and placeelseon a new line.Apply pattern:
- if (props.readOnly || props.disabled) return; + if (props.readOnly || props.disabled) + return;And:
- } else { + } + else {Repeat for the highlighted lines to clear all reported lint errors.
Also applies to: 116-121, 130-136, 142-146, 153-156, 218-226, 230-231, 260-264, 280-286
206-226: Also respectdisabledwhere actions are blocked.A few handlers only check
readOnly. Align withsubmit()by checkingdisabledtoo so the UI doesn’t react while disabled.Apply:
function cancel() { - if (props.readOnly) return; + if (props.readOnly || props.disabled) + return; emits('cancel', internalValue.value); } function clear() { - if (props.readOnly) return; // 直接返回,不执行后续逻辑 + if (props.readOnly || props.disabled) + return; // 直接返回,不执行后续逻辑 ... } function handleKeyDown(e: { target: HTMLTextAreaElement } & KeyboardEvent) { - if (props.readOnly) return; // 直接返回,不执行后续逻辑 + if (props.readOnly || props.disabled) + return; // 直接返回,不执行后续逻辑 ... } function focus(type = 'all') { - if (props.readOnly) { + if (props.readOnly || props.disabled) { return false; } ... }Also applies to: 268-287
apps/docs/en/components/mentionSender/index.md (1)
145-145: Clarify binding notation (kebab-case in templates).Use kebab-case for directive arguments in templates.
-| `openHeader` | Boolean | No | false | Whether to open the custom header of the input box, using `v-model:openHeader` for two-way binding +| `openHeader` | Boolean | No | false | Whether to open the custom header; two-way bind via `v-model:open-header` in templates.apps/docs/zh/components/mentionSender/index.md (1)
145-145: Unify binding notation and punctuation.Prefer kebab-case and end the sentence with “。”.
-| `openHeader` | Boolean | 否 | false | 输入框自定义头部是否打开,使用 `v-model:openHeader` 进行双向绑定 +| `openHeader` | Boolean | 否 | false | 输入框自定义头部是否打开,使用 `v-model:open-header` 进行双向绑定。apps/docs/en/components/sender/index.md (1)
103-103: Clarify binding notation (kebab-case in templates).Use kebab-case for directive arguments in templates.
-| `openHeader` | Boolean | No | false | Whether to open the custom header of the input box, using `v-model:openHeader` for two-way binding +| `openHeader` | Boolean | No | false | Whether to open the custom header; two-way bind via `v-model:open-header` in templates.apps/docs/zh/components/sender/demos/header.vue (1)
15-22: Use kebab-case in the recommended snippet.Match actual usage below to avoid confusion.
-<Sender v-model:openHeader="openHeader"> +<Sender v-model:open-header="openHeader">packages/core/src/stories/MentionSender/CustomSolt.vue (2)
9-9: Comment casing: use kebab-case in docs/comments to match actual binding.Change the comment to v-model:open-header for consistency with the template.
-const openHeader = ref(true); // 使用 v-model:openHeader 控制头部显示状态 +const openHeader = ref(true); // 使用 v-model:open-header 控制头部显示状态
124-124: Avoid
for layout spacing in stories.Prefer semantic spacing via CSS/margins to keep markup clean.
- <br /> + <!-- spacing handled by CSS, e.g., .content > .btn-row { margin-bottom: 8px } -->Also applies to: 139-139
apps/docs/en/components/sender/demos/header.vue (1)
30-30: Align comment with actual API.Use v-model:open-header in the comment for consistency.
-const openHeader = ref(true); // Use v-model:openHeader to control header display state +const openHeader = ref(true); // Use v-model:open-header to control header display statepackages/core/src/components/Sender/index.vue (6)
62-65: Block internal model updates when readOnly/disabled.Good guard; consider formatting to satisfy lint (if-newline).
- if (props.readOnly || props.disabled) return; + if (props.readOnly || props.disabled) + return;
92-95: Same guard for popover visibility is appropriate.Also apply newline style to pass lint.
- if (props.readOnly || props.disabled) return; + if (props.readOnly || props.disabled) + return;
100-158: Trigger watcher: remove unnecessary deep option for string; minor perf/readability.-watch( +watch( () => internalValue.value, (newVal, oldVal) => { - if (isComposing.value) return; + if (isComposing.value) + return; ... - }, - { deep: true, immediate: true } + }, + { immediate: true } )
301-336: Key handling respects readOnly and submitType; lint nits only.Functionally good. Consider fixing brace-style and if-newline to satisfy the linter.
- if (props.submitType === 'enter') { - _isComKeyDown ? _resetSelectionRange() : submit(); - } else { - _isComKeyDown ? submit() : _resetSelectionRange(); - } + if (props.submitType === 'enter') { + _isComKeyDown ? _resetSelectionRange() : submit(); + } + else { + _isComKeyDown ? submit() : _resetSelectionRange(); + }
446-450: Don’t render header wrapper when there’s no header slot.Avoid empty wrapper affecting layout if openHeader=true without a slot.
- <div v-if="headerOpenState" class="el-sender-header-wrap"> + <div v-if="headerOpenState && $slots.header" class="el-sender-header-wrap"> <div v-if="$slots.header" class="el-sender-header"> <slot name="header" /> </div> </div>
200-207: Confirm deprecation of openHeader() in types & code.SenderEmitsincludes'update:openHeader'(types.d.ts:60, index.vue:191) andopenHeaderis marked@deprecatedin index.vue (lines 197 & 211). Consider updating any external/docs (e.g. README) to note this deprecation.apps/docs/zh/components/mentionSender/demos/header.vue (1)
9-9: Prefer kebab-case in docs: v-model:open-headerUse kebab-case in templates to match Vue style and your actual demo usage.
-以下方法将在下个大版本中移除,推荐使用 `v-model:openHeader` 进行双向绑定控制: +以下方法将在下个大版本中移除,推荐使用 `v-model:open-header` 进行双向绑定控制:-使用 `v-model:openHeader` 进行双向绑定控制头部显示状态: +使用 `v-model:open-header` 进行双向绑定控制头部显示状态:Also applies to: 16-16
apps/docs/en/components/mentionSender/demos/header.vue (2)
19-22: Unify snippet with actual usage: use kebab-case argumentMatch the demo’s v-model:open-header to avoid confusing readers.
-<MentionSender v-model:openHeader="openHeader"> +<MentionSender v-model:open-header="openHeader"> <template #header>Header content</template> </MentionSender>
9-9: Docs phrasing: prefer v-model:open-header in templatesMinor consistency fix with Vue template conventions and your demo.
-It is recommended to use `v-model:openHeader` for two-way binding control: +It is recommended to use `v-model:open-header` for two-way binding control:-Use `v-model:openHeader` for two-way binding to control header display state: +Use `v-model:open-header` for two-way binding to control header display state:Also applies to: 16-16
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (18)
.gitignore(1 hunks)apps/docs/en/components/mentionSender/demos/header.vue(2 hunks)apps/docs/en/components/mentionSender/index.md(1 hunks)apps/docs/en/components/sender/demos/header.vue(2 hunks)apps/docs/en/components/sender/index.md(1 hunks)apps/docs/zh/components/mentionSender/demos/header.vue(2 hunks)apps/docs/zh/components/mentionSender/index.md(1 hunks)apps/docs/zh/components/sender/demos/header.vue(2 hunks)apps/docs/zh/components/sender/index.md(1 hunks)packages/core/components.d.ts(0 hunks)packages/core/src/components/MentionSender/index.vue(10 hunks)packages/core/src/components/MentionSender/types.d.ts(2 hunks)packages/core/src/components/Sender/index.vue(15 hunks)packages/core/src/components/Sender/types.d.ts(2 hunks)packages/core/src/stories/MentionSender/CustomSolt.vue(5 hunks)packages/core/src/stories/MentionSender/MentionSender.stories.ts(2 hunks)packages/core/src/stories/Sender/CustomSolt.vue(5 hunks)packages/core/src/stories/Sender/Sender.stories.ts(3 hunks)
💤 Files with no reviewable changes (1)
- packages/core/components.d.ts
🧰 Additional context used
🧬 Code graph analysis (5)
packages/core/src/components/Sender/types.d.ts (1)
packages/core/src/components/EditorSender/types.d.ts (2)
EditorProps(13-30)EditorSenderEmits(73-82)
packages/core/src/components/MentionSender/types.d.ts (2)
packages/core/src/components/EditorSender/types.d.ts (2)
EditorProps(13-30)EditorSenderEmits(73-82)packages/core/src/components/Conversations/types.d.ts (1)
ConversationsEmits(101-109)
packages/core/src/stories/Sender/Sender.stories.ts (1)
packages/core/src/stories/EditorSender/EditorSender.stories.ts (2)
setup(106-110)_args(105-116)
apps/docs/en/components/sender/index.md (1)
packages/core/src/components/EditorSender/types.d.ts (1)
EditorProps(13-30)
apps/docs/zh/components/sender/index.md (1)
packages/core/src/components/EditorSender/types.d.ts (1)
EditorProps(13-30)
🪛 ESLint
packages/core/src/components/MentionSender/index.vue
[error] 57-57: Expect newline after if
(antfu/if-newline)
[error] 116-116: Expect newline after if
(antfu/if-newline)
[error] 130-130: Expect newline after if
(antfu/if-newline)
[error] 132-132: Expect newline after if
(antfu/if-newline)
[error] 143-143: Expect newline after if
(antfu/if-newline)
[error] 144-144: Expect newline after if
(antfu/if-newline)
[error] 154-154: Expect newline after if
(antfu/if-newline)
[error] 185-185: Closing curly brace appears on the same line as the subsequent block.
(style/brace-style)
[error] 218-218: Expect newline after if
(antfu/if-newline)
[error] 223-223: Expect newline after if
(antfu/if-newline)
[error] 230-230: Expect newline after if
(antfu/if-newline)
[error] 261-261: Closing curly brace appears on the same line as the subsequent block.
(style/brace-style)
[error] 282-282: Closing curly brace appears on the same line as the subsequent block.
(style/brace-style)
[error] 284-284: Closing curly brace appears on the same line as the subsequent block.
(style/brace-style)
packages/core/src/components/Sender/index.vue
[error] 62-62: Expect newline after if
(antfu/if-newline)
[error] 92-92: Expect newline after if
(antfu/if-newline)
[error] 104-104: Expect newline after if
(antfu/if-newline)
[error] 123-123: Closing curly brace appears on the same line as the subsequent block.
(style/brace-style)
[error] 137-137: Closing curly brace appears on the same line as the subsequent block.
(style/brace-style)
[error] 152-152: Closing curly brace appears on the same line as the subsequent block.
(style/brace-style)
[error] 187-187: Expect newline after if
(antfu/if-newline)
[error] 201-201: Expect newline after if
(antfu/if-newline)
[error] 203-203: Expect newline after if
(antfu/if-newline)
[error] 214-214: Expect newline after if
(antfu/if-newline)
[error] 215-215: Expect newline after if
(antfu/if-newline)
[error] 225-225: Expect newline after if
(antfu/if-newline)
[error] 256-256: Closing curly brace appears on the same line as the subsequent block.
(style/brace-style)
[error] 289-289: Expect newline after if
(antfu/if-newline)
[error] 294-294: Expect newline after if
(antfu/if-newline)
[error] 301-301: Expect newline after if
(antfu/if-newline)
[error] 332-332: Closing curly brace appears on the same line as the subsequent block.
(style/brace-style)
[error] 353-353: Closing curly brace appears on the same line as the subsequent block.
(style/brace-style)
[error] 355-355: Closing curly brace appears on the same line as the subsequent block.
(style/brace-style)
🔇 Additional comments (25)
packages/core/src/components/Sender/types.d.ts (1)
25-27: LGTM: prop + v-model event shape are consistent.
openHeader?: booleanandupdate:openHeaderalign with Vue v-model conventions and mirror MentionSender.Also applies to: 60-60
packages/core/src/components/MentionSender/types.d.ts (1)
32-34: LGTM: public API matches Sender and supports v-model.The prop and event are correctly named and typed for two-way binding.
Also applies to: 58-58
packages/core/src/components/MentionSender/index.vue (1)
335-348: Confirm no conflict between exposed method name and prop name.Exposing
openHeaderwhile also having a prop namedopenHeaderis usually safe in<script setup>(expose controls the ref surface), but please confirm no tools/types rely on reading props via template refs. If necessary, alias exposed methods while keeping deprecated names for BC.packages/core/src/stories/MentionSender/MentionSender.stories.ts (2)
22-29: Hiding openHeader from controls makes sense here.Keeping it disabled in Controls to avoid confusion with the CustomSolt example is fine.
181-191: Add missing imports for ref/watch (unless auto-import is configured).This file uses
ref/watchwithout explicit imports; add them if auto-import isn’t enabled in Storybook.+import { ref, watch } from 'vue';apps/docs/zh/components/sender/demos/header.vue (1)
8-13: Good deprecation notice.Clear guidance toward
v-modelis appreciated.packages/core/src/stories/Sender/Sender.stories.ts (1)
22-29: Arg wiring looks fine.ArgTypes and default
args.openHeader = falseare consistent.Also applies to: 146-146
packages/core/src/stories/Sender/CustomSolt.vue (2)
10-11: OK to toggle via external state.The move to
openHeaderstate withv-modelaligns with the new API.
14-21: Also import onMounted/ref/computed if auto-import isn’t active.These are used (
onMounted,ref,computed) but not imported here.-import { onUnmounted } from 'vue'; +import { ref, computed, onMounted, onUnmounted } from 'vue';packages/core/src/stories/MentionSender/CustomSolt.vue (3)
40-45: LGTM: reactive toggle replaces imperative API cleanly.Toggling via local state aligns with the new v-model contract and keeps back-compat methods unused here.
143-143: No action required:v-model:open-headerbinding is correct. MentionSender declares anopenHeaderprop (in types.d.ts) and emitsupdate:openHeader(in index.vue), matching Sender’s API.
1-8: Auto-import plugin present in docs config. Vue APIs (ref, computed, onMounted, onBeforeUnmount, nextTick) are auto-imported via apps/docs/vite.config.mts, so explicit imports in CustomSolt.vue aren’t needed.apps/docs/en/components/sender/demos/header.vue (4)
8-13: Deprecation note is clear.Good call-out of the legacy methods and the v-model alternative.
32-38: LGTM: simple, readable state toggling.
51-55: LGTM: UX toggle label reflects state; binding uses v-model:open-header correctly.
58-67: LGTM: header slot content and close action demonstrate API well.packages/core/src/components/Sender/index.vue (5)
29-31: Prop default looks right.openHeader defaulting to false is sensible and backwards-compatible.
171-193: State bridge for v-model is solid; emits keep parent in sync.Nice separation (internalHeaderOpen + computed setter).
214-217: Deprecated closeHeader() retained appropriately.Matches the new state bridge; fine.
225-256: readOnly short-circuit in voice flow prevents accidental side effects.
289-297: Guarded cancel/clear respect readOnly; good.apps/docs/zh/components/mentionSender/demos/header.vue (2)
51-55: LGTM: toggle + v-model wiring is correctButton toggles state and binding uses v-model:open-header consistently with component API.
30-30: No explicitrefimport required
AutoImport in apps/docs/vite.config.mts hasimports: ['vue'], which auto-imports Vue APIs includingref.apps/docs/en/components/mentionSender/demos/header.vue (2)
51-55: LGTM: binding and slot usage look goodDemo correctly exercises two-way binding and header slot.
30-30: Auto-import ofrefis already configured
Theunplugin-auto-importplugin inapps/docs/vite.config.mtsincludesimports: ['vue'], sorefis available without an explicit import.
| ::: tip Recommended Usage | ||
| Use `v-model:openHeader` for two-way binding to control header display state: | ||
|
|
||
| ```vue | ||
| <Sender v-model:openHeader="openHeader"> | ||
| <template #header>Header content</template> | ||
| </Sender> | ||
| ``` |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Fix sample: use kebab-case argument in DOM templates.
In SFC/DOM templates, the v-model argument must be kebab-cased. Update the snippet.
-```vue
-<Sender v-model:openHeader="openHeader">
+```vue
+<Sender v-model:open-header="openHeader">
<template #header>Header content</template>
</Sender>
<details>
<summary>🤖 Prompt for AI Agents</summary>
In apps/docs/en/components/sender/demos/header.vue around lines 15 to 22, the
example uses a camelCase v-model argument (v-model:openHeader) which is invalid
in SFC/DOM templates; update the snippet to use kebab-case for the v-model
argument (v-model:open-header="openHeader") in the template example so it
follows Vue's DOM/SFC template requirements.
</details>
<!-- fingerprinting:phantom:medusa:chinchilla -->
<!-- This is an auto-generated comment by CodeRabbit -->
| <Sender v-model:openHeader="openHeader"> | ||
| <template #header>头部内容</template> | ||
| </Sender> | ||
| ``` |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Fix component tag and use kebab-case v-model arg in the snippet
This demo is for MentionSender but the snippet shows Sender and camelCase argument. Align with actual usage below.
Apply:
-<Sender v-model:openHeader="openHeader">
- <template #header>头部内容</template>
-</Sender>
+<MentionSender v-model:open-header="openHeader">
+ <template #header>头部内容</template>
+</MentionSender>📝 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.
| <Sender v-model:openHeader="openHeader"> | |
| <template #header>头部内容</template> | |
| </Sender> | |
| ``` | |
| <MentionSender v-model:open-header="openHeader"> | |
| <template #header>头部内容</template> | |
| </MentionSender> |
🤖 Prompt for AI Agents
In apps/docs/zh/components/mentionSender/demos/header.vue around lines 19 to 22,
the demo snippet incorrectly uses <Sender> and a camelCase v-model argument;
update the component tag to MentionSender and change the v-model argument to
kebab-case (v-model:open-header) so it matches the actual component API and the
usage shown elsewhere; ensure the slot template remains the same (template
#header) and that the binding syntax is consistent with other examples.
| | ------------------------- | -------------------- | -------- | -------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | ||
| | `v-model` | String | 否 | '' | 输入框的绑定值,使用 `v-model` 进行双向绑定。 | | ||
| | `placeholder` | String | 否 | '' | 输入框的提示语文本。 | | ||
| | `openHeader` | Boolean | 否 | false | 输入框自定义头部是否打开,使用 `v-model:openHeader` 进行双向绑定本。 | |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Fix typo and prefer kebab-case for v-model arg.
Remove the stray “本” and use kebab-case in template-facing docs.
-| `openHeader` | Boolean | 否 | false | 输入框自定义头部是否打开,使用 `v-model:openHeader` 进行双向绑定本。
+| `openHeader` | Boolean | 否 | false | 输入框自定义头部是否打开,使用 `v-model:open-header` 进行双向绑定。📝 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.
| | `openHeader` | Boolean | 否 | false | 输入框自定义头部是否打开,使用 `v-model:openHeader` 进行双向绑定本。 | | |
| | `openHeader` | Boolean | 否 | false | 输入框自定义头部是否打开,使用 `v-model:open-header` 进行双向绑定。 | |
🤖 Prompt for AI Agents
In apps/docs/zh/components/sender/index.md around line 103, the table cell has a
stray Chinese character "本" and uses camelCase for the v-model arg; remove the
stray "本" and change the example to use kebab-case for the template-facing
v-model binding (v-model:open-header) so the sentence reads without the extra
character and shows the preferred kebab-case usage.
| /** | ||
| * 打开头部容器 | ||
| * @deprecated 此方法将在下个大版本中移除,请使用 v-model:openHeader 代替 | ||
| * @returns {boolean} 是否成功打开 | ||
| */ | ||
| function openHeader() { | ||
| if (!slots.header) | ||
| return false; | ||
| if (!slots.header) return false; | ||
| if (props.readOnly) | ||
| return false; | ||
| if (props.readOnly) return false; | ||
| visiableHeader.value = true; | ||
| headerOpenState.value = true; | ||
| return true; | ||
| } | ||
| /** | ||
| * 关闭头部容器 | ||
| * @deprecated 此方法将在下个大版本中移除,请使用 v-model:openHeader 代替 | ||
| */ | ||
| function closeHeader() { | ||
| if (!slots.header) | ||
| return; | ||
| if (props.readOnly) | ||
| return; | ||
| visiableHeader.value = false; | ||
| if (!slots.header) return; | ||
| if (props.readOnly) return; | ||
| headerOpenState.value = false; | ||
| } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
💡 Verification agent
🧩 Analysis chain
Honor disabled state in methods and make return behavior consistent.
openHeader() should also respect disabled. closeHeader() should return a boolean or document it returns void; currently it silently no-ops when disabled and always succeeds when disabled via setter guard. Suggest returning booleans for both while keeping deprecated API.
Apply:
function openHeader() {
- if (!slots.header) return false;
- if (props.readOnly) return false;
+ if (!slots.header) return false;
+ if (props.readOnly || props.disabled) return false;
headerOpenState.value = true;
return true;
}
/**
* 关闭头部容器
* @deprecated 此方法将在下个大版本中移除,请使用 v-model:openHeader 代替
*/
function closeHeader() {
- if (!slots.header) return;
- if (props.readOnly) return;
- headerOpenState.value = false;
+ if (!slots.header) return false;
+ if (props.readOnly || props.disabled) return false;
+ headerOpenState.value = false;
+ return true;
}If changing closeHeader’s return type is not acceptable for compatibility, keep void but still add the disabled guard and update docs accordingly.
🏁 Script executed:
#!/bin/bash
# Locate props definitions and check for disabled prop in MentionSender component
grep -n "defineProps" packages/core/src/components/MentionSender/index.vue || true
grep -n "props\\s*:" packages/core/src/components/MentionSender/index.vue || true
grep -n "disabled" packages/core/src/components/MentionSender/index.vue || true
# Show the openHeader/closeHeader methods for context
sed -n '120,160p' packages/core/src/components/MentionSender/index.vueLength of output: 1372
Ensure props.disabled is checked and return behavior aligned in header methods
- In packages/core/src/components/MentionSender/index.vue’s openHeader and closeHeader, add
props.disabledto the early-return guard. - Make closeHeader return a boolean (with
@returns {boolean}) to match openHeader, or if that breaks compatibility, retain its void signature but update its JSDoc to note it returns void while still honoring the disabled check.
🧰 Tools
🪛 ESLint
[error] 130-130: Expect newline after if
(antfu/if-newline)
[error] 132-132: Expect newline after if
(antfu/if-newline)
[error] 143-143: Expect newline after if
(antfu/if-newline)
[error] 144-144: Expect newline after if
(antfu/if-newline)
🤖 Prompt for AI Agents
In packages/core/src/components/MentionSender/index.vue around lines 124 to 146,
the openHeader/closeHeader methods currently skip checking props.disabled and
closeHeader returns void while openHeader returns boolean; update both methods
to early-return when props.disabled is true (in the same way they already check
props.readOnly) and make closeHeader return a boolean to match openHeader
(return false on early exits and true when it actually closes the header), or if
you must preserve the void signature for compatibility, leave closeHeader's
signature as void but update its JSDoc to @returns {void} and still add the
props.disabled guard so it honors the disabled state.
| v-model:openHeader="openHeader" | ||
| v-model:triggerPopoverVisible="triggerVisible" | ||
| /> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Bug: v-model bound to undefined openHeader.
openHeader isn’t defined in setup(), causing a runtime error. Define it and sync with args; also import ref/watch if auto-import isn’t enabled.
+import { ref, watch } from 'vue';
@@
setup() {
- const model = ref(args.modelValue);
- const triggerVisible = ref(args.triggerPopoverVisible);
+ const model = ref(args.modelValue);
+ const triggerVisible = ref(args.triggerPopoverVisible);
+ const openHeader = ref(args.openHeader);
@@
watch(triggerVisible, val => {
args.triggerPopoverVisible = val;
});
+ watch(openHeader, val => {
+ args.openHeader = val;
+ });
@@
- triggerVisible
+ triggerVisible,
+ openHeader
};
},
@@
- v-model:openHeader="openHeader"
+ v-model:openHeader="openHeader"📝 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.
| v-model:openHeader="openHeader" | |
| v-model:triggerPopoverVisible="triggerVisible" | |
| /> | |
| // ← at the top of the file, alongside your other imports | |
| import { ref, watch } from 'vue'; | |
| // … | |
| export const Default: StoryFn = (args) => ({ | |
| components: { Sender }, | |
| setup() { | |
| const model = ref(args.modelValue); | |
| const triggerVisible = ref(args.triggerPopoverVisible); | |
| const openHeader = ref(args.openHeader); | |
| watch(model, val => { | |
| args.modelValue = val; | |
| }); | |
| watch(triggerVisible, val => { | |
| args.triggerPopoverVisible = val; | |
| }); | |
| watch(openHeader, val => { | |
| args.openHeader = val; | |
| }); | |
| return { | |
| args, | |
| model, | |
| triggerVisible, | |
| openHeader | |
| }; | |
| }, | |
| template: ` | |
| <Sender | |
| v-model:modelValue="model" | |
| v-model:openHeader="openHeader" | |
| v-model:triggerPopoverVisible="triggerVisible" | |
| /> | |
| ` | |
| }); |
🤖 Prompt for AI Agents
In packages/core/src/stories/Sender/Sender.stories.ts around lines 204-206, the
template binds v-model:openHeader to an undefined openHeader which causes a
runtime error; define openHeader in setup() as a reactive ref, import ref (and
watch if not auto-imported), initialize it from args (e.g.,
ref(Boolean(args.openHeader))) and set up a watch to keep args and openHeader in
sync (or update args when openHeader changes) so the v-model has a defined
reactive variable.
MentionSender, Sender组件
1、新增 openHeader 属性,方便控制自定义头部,默认展开关闭。
2、向下兼容openHeader和closeHeader方法。
3、中英文档 添加 openHeader 属性 并调整组件示例代码
Refs: #319
Summary by CodeRabbit