diff --git a/controlgallery/AtomUIGallery/GeneratedFiles/AtomUI.Generator/AtomUI.Generator.LanguageGenerator/LanguageProviderPool.g.cs b/controlgallery/AtomUIGallery/GeneratedFiles/AtomUI.Generator/AtomUI.Generator.LanguageGenerator/LanguageProviderPool.g.cs
index f56acc986..595e447a1 100644
--- a/controlgallery/AtomUIGallery/GeneratedFiles/AtomUI.Generator/AtomUI.Generator.LanguageGenerator/LanguageProviderPool.g.cs
+++ b/controlgallery/AtomUIGallery/GeneratedFiles/AtomUI.Generator/AtomUI.Generator.LanguageGenerator/LanguageProviderPool.g.cs
@@ -11792,9 +11792,13 @@ namespace AtomUI.Theme.Language
dictionary[global::AtomUIGallery.Localization.MentionsShowCaseLangResourceKind.InfoNamespaceLabel] = global::AtomUIGallery.ShowCases.Mentions.en_US.InfoNamespaceLabel;
dictionary[global::AtomUIGallery.Localization.MentionsShowCaseLangResourceKind.InfoPackageLabel] = global::AtomUIGallery.ShowCases.Mentions.en_US.InfoPackageLabel;
dictionary[global::AtomUIGallery.Localization.MentionsShowCaseLangResourceKind.P2PlaceholderTextBorderless] = global::AtomUIGallery.ShowCases.Mentions.en_US.P2PlaceholderTextBorderless;
+ dictionary[global::AtomUIGallery.Localization.MentionsShowCaseLangResourceKind.P2PlaceholderTextCustom] = global::AtomUIGallery.ShowCases.Mentions.en_US.P2PlaceholderTextCustom;
dictionary[global::AtomUIGallery.Localization.MentionsShowCaseLangResourceKind.P2PlaceholderTextFilled] = global::AtomUIGallery.ShowCases.Mentions.en_US.P2PlaceholderTextFilled;
dictionary[global::AtomUIGallery.Localization.MentionsShowCaseLangResourceKind.P2PlaceholderTextInputToMentionPeopleToMentionTag] = global::AtomUIGallery.ShowCases.Mentions.en_US.P2PlaceholderTextInputToMentionPeopleToMentionTag;
+ dictionary[global::AtomUIGallery.Localization.MentionsShowCaseLangResourceKind.P2PlaceholderTextLarge] = global::AtomUIGallery.ShowCases.Mentions.en_US.P2PlaceholderTextLarge;
+ dictionary[global::AtomUIGallery.Localization.MentionsShowCaseLangResourceKind.P2PlaceholderTextMiddle] = global::AtomUIGallery.ShowCases.Mentions.en_US.P2PlaceholderTextMiddle;
dictionary[global::AtomUIGallery.Localization.MentionsShowCaseLangResourceKind.P2PlaceholderTextOutlined] = global::AtomUIGallery.ShowCases.Mentions.en_US.P2PlaceholderTextOutlined;
+ dictionary[global::AtomUIGallery.Localization.MentionsShowCaseLangResourceKind.P2PlaceholderTextSmall] = global::AtomUIGallery.ShowCases.Mentions.en_US.P2PlaceholderTextSmall;
dictionary[global::AtomUIGallery.Localization.MentionsShowCaseLangResourceKind.P2PlaceholderTextThisIsDisabledMentions] = global::AtomUIGallery.ShowCases.Mentions.en_US.P2PlaceholderTextThisIsDisabledMentions;
dictionary[global::AtomUIGallery.Localization.MentionsShowCaseLangResourceKind.P2PlaceholderTextThisIsReadonlyMentions] = global::AtomUIGallery.ShowCases.Mentions.en_US.P2PlaceholderTextThisIsReadonlyMentions;
dictionary[global::AtomUIGallery.Localization.MentionsShowCaseLangResourceKind.P2PlaceholderTextUnderlined] = global::AtomUIGallery.ShowCases.Mentions.en_US.P2PlaceholderTextUnderlined;
@@ -11805,6 +11809,8 @@ namespace AtomUI.Theme.Language
dictionary[global::AtomUIGallery.Localization.MentionsShowCaseLangResourceKind.ScenarioApi] = global::AtomUIGallery.ShowCases.Mentions.en_US.ScenarioApi;
dictionary[global::AtomUIGallery.Localization.MentionsShowCaseLangResourceKind.ScenarioDesignToken] = global::AtomUIGallery.ShowCases.Mentions.en_US.ScenarioDesignToken;
dictionary[global::AtomUIGallery.Localization.MentionsShowCaseLangResourceKind.ScenarioExamples] = global::AtomUIGallery.ShowCases.Mentions.en_US.ScenarioExamples;
+ dictionary[global::AtomUIGallery.Localization.MentionsShowCaseLangResourceKind.SizeTypeDescription] = global::AtomUIGallery.ShowCases.Mentions.en_US.SizeTypeDescription;
+ dictionary[global::AtomUIGallery.Localization.MentionsShowCaseLangResourceKind.SizeTypeTitle] = global::AtomUIGallery.ShowCases.Mentions.en_US.SizeTypeTitle;
dictionary[global::AtomUIGallery.Localization.MentionsShowCaseLangResourceKind.StatusDescription] = global::AtomUIGallery.ShowCases.Mentions.en_US.StatusDescription;
dictionary[global::AtomUIGallery.Localization.MentionsShowCaseLangResourceKind.StatusTitle] = global::AtomUIGallery.ShowCases.Mentions.en_US.StatusTitle;
dictionary[global::AtomUIGallery.Localization.MentionsShowCaseLangResourceKind.TokenColumnDescription] = global::AtomUIGallery.ShowCases.Mentions.en_US.TokenColumnDescription;
@@ -11887,9 +11893,13 @@ namespace AtomUI.Theme.Language
dictionary[global::AtomUIGallery.Localization.MentionsShowCaseLangResourceKind.InfoNamespaceLabel] = global::AtomUIGallery.ShowCases.Mentions.zh_CN.InfoNamespaceLabel;
dictionary[global::AtomUIGallery.Localization.MentionsShowCaseLangResourceKind.InfoPackageLabel] = global::AtomUIGallery.ShowCases.Mentions.zh_CN.InfoPackageLabel;
dictionary[global::AtomUIGallery.Localization.MentionsShowCaseLangResourceKind.P2PlaceholderTextBorderless] = global::AtomUIGallery.ShowCases.Mentions.zh_CN.P2PlaceholderTextBorderless;
+ dictionary[global::AtomUIGallery.Localization.MentionsShowCaseLangResourceKind.P2PlaceholderTextCustom] = global::AtomUIGallery.ShowCases.Mentions.zh_CN.P2PlaceholderTextCustom;
dictionary[global::AtomUIGallery.Localization.MentionsShowCaseLangResourceKind.P2PlaceholderTextFilled] = global::AtomUIGallery.ShowCases.Mentions.zh_CN.P2PlaceholderTextFilled;
dictionary[global::AtomUIGallery.Localization.MentionsShowCaseLangResourceKind.P2PlaceholderTextInputToMentionPeopleToMentionTag] = global::AtomUIGallery.ShowCases.Mentions.zh_CN.P2PlaceholderTextInputToMentionPeopleToMentionTag;
+ dictionary[global::AtomUIGallery.Localization.MentionsShowCaseLangResourceKind.P2PlaceholderTextLarge] = global::AtomUIGallery.ShowCases.Mentions.zh_CN.P2PlaceholderTextLarge;
+ dictionary[global::AtomUIGallery.Localization.MentionsShowCaseLangResourceKind.P2PlaceholderTextMiddle] = global::AtomUIGallery.ShowCases.Mentions.zh_CN.P2PlaceholderTextMiddle;
dictionary[global::AtomUIGallery.Localization.MentionsShowCaseLangResourceKind.P2PlaceholderTextOutlined] = global::AtomUIGallery.ShowCases.Mentions.zh_CN.P2PlaceholderTextOutlined;
+ dictionary[global::AtomUIGallery.Localization.MentionsShowCaseLangResourceKind.P2PlaceholderTextSmall] = global::AtomUIGallery.ShowCases.Mentions.zh_CN.P2PlaceholderTextSmall;
dictionary[global::AtomUIGallery.Localization.MentionsShowCaseLangResourceKind.P2PlaceholderTextThisIsDisabledMentions] = global::AtomUIGallery.ShowCases.Mentions.zh_CN.P2PlaceholderTextThisIsDisabledMentions;
dictionary[global::AtomUIGallery.Localization.MentionsShowCaseLangResourceKind.P2PlaceholderTextThisIsReadonlyMentions] = global::AtomUIGallery.ShowCases.Mentions.zh_CN.P2PlaceholderTextThisIsReadonlyMentions;
dictionary[global::AtomUIGallery.Localization.MentionsShowCaseLangResourceKind.P2PlaceholderTextUnderlined] = global::AtomUIGallery.ShowCases.Mentions.zh_CN.P2PlaceholderTextUnderlined;
@@ -11900,6 +11910,8 @@ namespace AtomUI.Theme.Language
dictionary[global::AtomUIGallery.Localization.MentionsShowCaseLangResourceKind.ScenarioApi] = global::AtomUIGallery.ShowCases.Mentions.zh_CN.ScenarioApi;
dictionary[global::AtomUIGallery.Localization.MentionsShowCaseLangResourceKind.ScenarioDesignToken] = global::AtomUIGallery.ShowCases.Mentions.zh_CN.ScenarioDesignToken;
dictionary[global::AtomUIGallery.Localization.MentionsShowCaseLangResourceKind.ScenarioExamples] = global::AtomUIGallery.ShowCases.Mentions.zh_CN.ScenarioExamples;
+ dictionary[global::AtomUIGallery.Localization.MentionsShowCaseLangResourceKind.SizeTypeDescription] = global::AtomUIGallery.ShowCases.Mentions.zh_CN.SizeTypeDescription;
+ dictionary[global::AtomUIGallery.Localization.MentionsShowCaseLangResourceKind.SizeTypeTitle] = global::AtomUIGallery.ShowCases.Mentions.zh_CN.SizeTypeTitle;
dictionary[global::AtomUIGallery.Localization.MentionsShowCaseLangResourceKind.StatusDescription] = global::AtomUIGallery.ShowCases.Mentions.zh_CN.StatusDescription;
dictionary[global::AtomUIGallery.Localization.MentionsShowCaseLangResourceKind.StatusTitle] = global::AtomUIGallery.ShowCases.Mentions.zh_CN.StatusTitle;
dictionary[global::AtomUIGallery.Localization.MentionsShowCaseLangResourceKind.TokenColumnDescription] = global::AtomUIGallery.ShowCases.Mentions.zh_CN.TokenColumnDescription;
@@ -11982,9 +11994,13 @@ namespace AtomUI.Theme.Language
dictionary[global::AtomUIGallery.Localization.MentionsShowCaseLangResourceKind.InfoNamespaceLabel] = global::AtomUIGallery.ShowCases.Mentions.zh_TW.InfoNamespaceLabel;
dictionary[global::AtomUIGallery.Localization.MentionsShowCaseLangResourceKind.InfoPackageLabel] = global::AtomUIGallery.ShowCases.Mentions.zh_TW.InfoPackageLabel;
dictionary[global::AtomUIGallery.Localization.MentionsShowCaseLangResourceKind.P2PlaceholderTextBorderless] = global::AtomUIGallery.ShowCases.Mentions.zh_TW.P2PlaceholderTextBorderless;
+ dictionary[global::AtomUIGallery.Localization.MentionsShowCaseLangResourceKind.P2PlaceholderTextCustom] = global::AtomUIGallery.ShowCases.Mentions.zh_TW.P2PlaceholderTextCustom;
dictionary[global::AtomUIGallery.Localization.MentionsShowCaseLangResourceKind.P2PlaceholderTextFilled] = global::AtomUIGallery.ShowCases.Mentions.zh_TW.P2PlaceholderTextFilled;
dictionary[global::AtomUIGallery.Localization.MentionsShowCaseLangResourceKind.P2PlaceholderTextInputToMentionPeopleToMentionTag] = global::AtomUIGallery.ShowCases.Mentions.zh_TW.P2PlaceholderTextInputToMentionPeopleToMentionTag;
+ dictionary[global::AtomUIGallery.Localization.MentionsShowCaseLangResourceKind.P2PlaceholderTextLarge] = global::AtomUIGallery.ShowCases.Mentions.zh_TW.P2PlaceholderTextLarge;
+ dictionary[global::AtomUIGallery.Localization.MentionsShowCaseLangResourceKind.P2PlaceholderTextMiddle] = global::AtomUIGallery.ShowCases.Mentions.zh_TW.P2PlaceholderTextMiddle;
dictionary[global::AtomUIGallery.Localization.MentionsShowCaseLangResourceKind.P2PlaceholderTextOutlined] = global::AtomUIGallery.ShowCases.Mentions.zh_TW.P2PlaceholderTextOutlined;
+ dictionary[global::AtomUIGallery.Localization.MentionsShowCaseLangResourceKind.P2PlaceholderTextSmall] = global::AtomUIGallery.ShowCases.Mentions.zh_TW.P2PlaceholderTextSmall;
dictionary[global::AtomUIGallery.Localization.MentionsShowCaseLangResourceKind.P2PlaceholderTextThisIsDisabledMentions] = global::AtomUIGallery.ShowCases.Mentions.zh_TW.P2PlaceholderTextThisIsDisabledMentions;
dictionary[global::AtomUIGallery.Localization.MentionsShowCaseLangResourceKind.P2PlaceholderTextThisIsReadonlyMentions] = global::AtomUIGallery.ShowCases.Mentions.zh_TW.P2PlaceholderTextThisIsReadonlyMentions;
dictionary[global::AtomUIGallery.Localization.MentionsShowCaseLangResourceKind.P2PlaceholderTextUnderlined] = global::AtomUIGallery.ShowCases.Mentions.zh_TW.P2PlaceholderTextUnderlined;
@@ -11995,6 +12011,8 @@ namespace AtomUI.Theme.Language
dictionary[global::AtomUIGallery.Localization.MentionsShowCaseLangResourceKind.ScenarioApi] = global::AtomUIGallery.ShowCases.Mentions.zh_TW.ScenarioApi;
dictionary[global::AtomUIGallery.Localization.MentionsShowCaseLangResourceKind.ScenarioDesignToken] = global::AtomUIGallery.ShowCases.Mentions.zh_TW.ScenarioDesignToken;
dictionary[global::AtomUIGallery.Localization.MentionsShowCaseLangResourceKind.ScenarioExamples] = global::AtomUIGallery.ShowCases.Mentions.zh_TW.ScenarioExamples;
+ dictionary[global::AtomUIGallery.Localization.MentionsShowCaseLangResourceKind.SizeTypeDescription] = global::AtomUIGallery.ShowCases.Mentions.zh_TW.SizeTypeDescription;
+ dictionary[global::AtomUIGallery.Localization.MentionsShowCaseLangResourceKind.SizeTypeTitle] = global::AtomUIGallery.ShowCases.Mentions.zh_TW.SizeTypeTitle;
dictionary[global::AtomUIGallery.Localization.MentionsShowCaseLangResourceKind.StatusDescription] = global::AtomUIGallery.ShowCases.Mentions.zh_TW.StatusDescription;
dictionary[global::AtomUIGallery.Localization.MentionsShowCaseLangResourceKind.StatusTitle] = global::AtomUIGallery.ShowCases.Mentions.zh_TW.StatusTitle;
dictionary[global::AtomUIGallery.Localization.MentionsShowCaseLangResourceKind.TokenColumnDescription] = global::AtomUIGallery.ShowCases.Mentions.zh_TW.TokenColumnDescription;
diff --git a/controlgallery/AtomUIGallery/GeneratedFiles/AtomUI.Generator/AtomUI.Generator.LanguageGenerator/LanguageResourceConst.g.cs b/controlgallery/AtomUIGallery/GeneratedFiles/AtomUI.Generator/AtomUI.Generator.LanguageGenerator/LanguageResourceConst.g.cs
index 45bb73bf6..b95beefbf 100644
--- a/controlgallery/AtomUIGallery/GeneratedFiles/AtomUI.Generator/AtomUI.Generator.LanguageGenerator/LanguageResourceConst.g.cs
+++ b/controlgallery/AtomUIGallery/GeneratedFiles/AtomUI.Generator/AtomUI.Generator.LanguageGenerator/LanguageResourceConst.g.cs
@@ -3770,9 +3770,13 @@ namespace AtomUIGallery.Localization
InfoNamespaceLabel,
InfoPackageLabel,
P2PlaceholderTextBorderless,
+ P2PlaceholderTextCustom,
P2PlaceholderTextFilled,
P2PlaceholderTextInputToMentionPeopleToMentionTag,
+ P2PlaceholderTextLarge,
+ P2PlaceholderTextMiddle,
P2PlaceholderTextOutlined,
+ P2PlaceholderTextSmall,
P2PlaceholderTextThisIsDisabledMentions,
P2PlaceholderTextThisIsReadonlyMentions,
P2PlaceholderTextUnderlined,
@@ -3783,6 +3787,8 @@ namespace AtomUIGallery.Localization
ScenarioApi,
ScenarioDesignToken,
ScenarioExamples,
+ SizeTypeDescription,
+ SizeTypeTitle,
StatusDescription,
StatusTitle,
TokenColumnDescription,
diff --git a/controlgallery/AtomUIGallery/ShowCases/DataEntry/Mentions/Localization/en_US.cs b/controlgallery/AtomUIGallery/ShowCases/DataEntry/Mentions/Localization/en_US.cs
index cb6e51f74..cbaf47bdc 100644
--- a/controlgallery/AtomUIGallery/ShowCases/DataEntry/Mentions/Localization/en_US.cs
+++ b/controlgallery/AtomUIGallery/ShowCases/DataEntry/Mentions/Localization/en_US.cs
@@ -8,6 +8,8 @@ internal partial class en_US : LanguageProvider
{
public const string BasicTitle = "Basic";
public const string BasicDescription = "The simplest use.";
+ public const string SizeTypeTitle = "Mentions size";
+ public const string SizeTypeDescription = "Mentions supports large, middle, small, and Custom sizes with local height and font overrides.";
public const string VariantsTitle = "Variants";
public const string VariantsDescription = "Variants of Mentions, there are four variants: outlined filled borderless and underlined.";
public const string AsynchronousLoadingTitle = "Asynchronous loading";
@@ -24,6 +26,10 @@ internal partial class en_US : LanguageProvider
public const string AutoSizeDescription = "Height autoSize.";
public const string WithClearIconTitle = "With clear icon";
public const string WithClearIconDescription = "Customize clear button.";
+ public const string P2PlaceholderTextLarge = "Large";
+ public const string P2PlaceholderTextMiddle = "Middle";
+ public const string P2PlaceholderTextSmall = "Small";
+ public const string P2PlaceholderTextCustom = "Custom";
public const string P2PlaceholderTextOutlined = "Outlined";
public const string P2PlaceholderTextFilled = "Filled";
public const string P2PlaceholderTextBorderless = "Borderless";
diff --git a/controlgallery/AtomUIGallery/ShowCases/DataEntry/Mentions/Localization/zh_CN.cs b/controlgallery/AtomUIGallery/ShowCases/DataEntry/Mentions/Localization/zh_CN.cs
index 58bf80f42..4650e48e6 100644
--- a/controlgallery/AtomUIGallery/ShowCases/DataEntry/Mentions/Localization/zh_CN.cs
+++ b/controlgallery/AtomUIGallery/ShowCases/DataEntry/Mentions/Localization/zh_CN.cs
@@ -8,6 +8,8 @@ internal partial class zh_CN : LanguageProvider
{
public const string BasicTitle = "基础用法";
public const string BasicDescription = "最简单的用法。";
+ public const string SizeTypeTitle = "Mentions 尺寸";
+ public const string SizeTypeDescription = "Mentions 支持大号、中号、小号,也支持通过 Custom 配合本地高度和字号自定义。";
public const string VariantsTitle = "变体";
public const string VariantsDescription = "Mentions 提供四种变体:描边、填充、无边框和下划线。";
public const string AsynchronousLoadingTitle = "异步加载";
@@ -24,6 +26,10 @@ internal partial class zh_CN : LanguageProvider
public const string AutoSizeDescription = "高度自动调整。";
public const string WithClearIconTitle = "带清除图标";
public const string WithClearIconDescription = "自定义清除按钮。";
+ public const string P2PlaceholderTextLarge = "大号";
+ public const string P2PlaceholderTextMiddle = "中号";
+ public const string P2PlaceholderTextSmall = "小号";
+ public const string P2PlaceholderTextCustom = "自定义";
public const string P2PlaceholderTextOutlined = "线框风格";
public const string P2PlaceholderTextFilled = "填充风格";
public const string P2PlaceholderTextBorderless = "无边框";
diff --git a/controlgallery/AtomUIGallery/ShowCases/DataEntry/Mentions/Localization/zh_TW.cs b/controlgallery/AtomUIGallery/ShowCases/DataEntry/Mentions/Localization/zh_TW.cs
index 410fbfc5c..e10ac3322 100644
--- a/controlgallery/AtomUIGallery/ShowCases/DataEntry/Mentions/Localization/zh_TW.cs
+++ b/controlgallery/AtomUIGallery/ShowCases/DataEntry/Mentions/Localization/zh_TW.cs
@@ -8,6 +8,8 @@ internal partial class zh_TW : LanguageProvider
{
public const string BasicTitle = "基礎用法";
public const string BasicDescription = "最簡單的用法。";
+ public const string SizeTypeTitle = "Mentions 尺寸";
+ public const string SizeTypeDescription = "Mentions 支持大號、中號、小號,也支持通過 Custom 配合本地高度和字號自定義。";
public const string VariantsTitle = "變體";
public const string VariantsDescription = "Mentions 提供四種變體:描邊、填充、無邊框和下划線。";
public const string AsynchronousLoadingTitle = "異步加載";
@@ -24,6 +26,10 @@ internal partial class zh_TW : LanguageProvider
public const string AutoSizeDescription = "高度自動調整。";
public const string WithClearIconTitle = "帶清除圖標";
public const string WithClearIconDescription = "自定義清除按鈕。";
+ public const string P2PlaceholderTextLarge = "大號";
+ public const string P2PlaceholderTextMiddle = "中號";
+ public const string P2PlaceholderTextSmall = "小號";
+ public const string P2PlaceholderTextCustom = "自定義";
public const string P2PlaceholderTextOutlined = "線框風格";
public const string P2PlaceholderTextFilled = "填充風格";
public const string P2PlaceholderTextBorderless = "無邊框";
diff --git a/controlgallery/AtomUIGallery/ShowCases/DataEntry/Mentions/Views/MentionsShowCase.axaml b/controlgallery/AtomUIGallery/ShowCases/DataEntry/Mentions/Views/MentionsShowCase.axaml
index f61d29e50..ea12558c1 100644
--- a/controlgallery/AtomUIGallery/ShowCases/DataEntry/Mentions/Views/MentionsShowCase.axaml
+++ b/controlgallery/AtomUIGallery/ShowCases/DataEntry/Mentions/Views/MentionsShowCase.axaml
@@ -2,6 +2,7 @@
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
x:Class="AtomUIGallery.ShowCases.Mentions.MentionsShowCase"
xmlns:atom="https://atomui.net"
+ xmlns:antdicons="https://atomui.net/icons/antdesign"
xmlns:gallery="https://atomui.net/oss-controls/gallery"
xmlns:vm="using:AtomUIGallery.ShowCases.Mentions"
x:DataType="vm:MentionsViewModel">
@@ -144,6 +145,41 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
?` | mention 触发前缀。当前触发识别只支持长度为 1 的字符串。默认值为 `["@"]`。 |
+| `Split` | `string?` | 插入候选项时使用的分隔符。为空时默认用空格包裹 mention 文本。 |
+| `OptionsSource` | `IEnumerable?` | 本地候选项集合。集合变更会同步到内部缓存和候选视图。 |
+| `OptionsAsyncLoader` | `IMentionOptionsAsyncLoader?` | 异步候选加载器。存在时,触发候选弹层会优先使用异步加载。 |
+| `OptionTemplate` | `IDataTemplate?` | 候选项显示模板。默认模板显示 `IMentionOption.Header`。 |
+| `Filter` | `IValueFilter?` | 候选过滤器。为空时使用 contains 过滤。 |
+| `FilterValueSelector` | `DefaultFilterValueSelector?` | 从候选项提取过滤文本的 selector。 |
+| `DisplayCandidateCount` | `int` | 弹层可显示的候选项数量,用于计算最大高度。默认 `10`。 |
+
+弹层与异步 API:
+
+| API | 类型 | 语义 |
+| --- | --- | --- |
+| `Placement` | `MentionsPlacementMode` | 候选弹层相对触发位置的展开方向,默认 `Bottom`。 |
+| `IsDropDownOpen` | `bool` | 候选弹层打开状态。 |
+| `ShouldUseOverlayPopup` | `bool` | 是否使用 overlay popup 宿主,默认 `true`。 |
+| `AsyncLoadDebounce` | `TimeSpan` | 异步加载前的防抖时间,默认 `TimeSpan.Zero`,值必须非负。 |
+| `AsyncLoadTimeout` | `TimeSpan` | 异步加载超时时间,默认 `10` 秒。 |
+| `IsLoading` | `bool` | 异步或事件填充过程中的内部 loading 状态,只读公开。 |
+
+输入表面 API:
+
+| API | 类型 | 语义 |
+| --- | --- | --- |
+| `SizeType` | `CustomizableSizeType` | 输入尺寸密度。 |
+| `StyleVariant` | `InputControlStyleVariant` | 输入表面样式。 |
+| `Status` | `InputControlStatus` | 输入反馈状态。 |
+| `ContentLeftAddOn` / `ContentRightAddOn` | `object?` | 内部左右附加内容,传递给内部 `MentionTextArea`。 |
+| `ContentLeftAddOnTemplate` / `ContentRightAddOnTemplate` | `IDataTemplate?` | 内部左右附加内容模板。 |
+| `IsMotionEnabled` | `bool` | 内部输入壳体、候选列表和 popup 动效开关。 |
+
+候选项契约:
+
+| 类型 | 语义 |
+| --- | --- |
+| `IMentionOption.Key` | 候选项稳定 key,可作为过滤候选值回退。 |
+| `IMentionOption.Header` | 候选项显示内容,默认模板显示该值。 |
+| `IMentionOption.Value` | 插入文本时优先使用的值。 |
+| `IMentionOption.IsEnabled` | 候选项启用状态,供候选列表视觉和选择逻辑使用。 |
+
+事件契约:
+
+| 事件 | 语义 |
+| --- | --- |
+| `CandidateTriggered` | 触发符被识别时触发,事件参数包含触发字符。 |
+| `Populating` | 候选弹层准备填充前触发,可取消默认填充并由业务手动更新候选集合。 |
+| `Populated` | 候选视图刷新后触发,事件参数包含只读候选视图。 |
+| `OptionsLoaded` | 异步 loader 完成后触发,包含加载结果或错误状态。 |
+| `DropDownOpening` / `DropDownClosing` | 弹层打开/关闭前触发,可取消。 |
+| `DropDownOpened` / `DropDownClosed` | 弹层打开/关闭后触发。 |
+
+稳定 template part:
+
+| Template Part | 类型 | 职责 |
+| --- | --- | --- |
+| `PART_TextArea` | `MentionTextArea` | 文本输入、触发符识别、过滤值同步和候选插入。 |
+| `PART_Popup` | `Popup` | 候选弹层宿主。 |
+| `PART_CandidateList` | `ICandidateList` / `CandidateList` | 候选项展示、键盘导航、提交和取消。 |
+| `PopupFrame` | `Border` | 候选弹层背景、圆角、宽度、高度和 padding。 |
+| `LoadingIndicator` | `Spin` | 异步候选加载状态展示。 |
+
+`EmptyIndicator`、`EmptyIndicatorTemplate`、`IsShowEmptyIndicator` 和 `EmptyIndicatorPadding` 是当前 public surface 的一部分;默认 `MentionsTheme` 尚未把这些属性绑定到候选弹层视觉结构中,维护时不能把它们描述为已经稳定生效的默认视觉契约。
+
+## 4. 行为与状态模型
+
+Mentions 的核心状态流:
+
+```text
+Value / DefaultValue
+ ↓
+MentionTextArea.Text
+ ↓
+Text input + caret position
+ ↓
+TriggerPrefix scan
+ ↓
+FilterValue + CandidateOpenRequest
+ ↓
+Populate / async load / filter
+ ↓
+CandidateList view
+ ↓
+Commit option
+ ↓
+Insert mention text back into Value
+```
+
+触发符识别从当前 `CaretIndex` 向前扫描,遇到空白或控制字符停止。只有长度为 1 的 `TriggerPrefix` 项会被识别。触发后,`MentionTextArea` 计算触发字符位置和过滤文本,并向外请求打开候选弹层。
+
+候选填充优先级:
+
+```text
+OptionsAsyncLoader != null
+ → async LoadAsync(FilterValue, token)
+ → OptionsLoaded
+ → OptionsSource = result.Data
+ → PopulateComplete()
+
+OptionsAsyncLoader == null
+ → Populating(FilterValue)
+ → if !Cancel PopulateComplete()
+```
+
+弹层状态优先级:
+
+```text
+Disabled / invisible / window deactivated
+> DropDownClosing cancellation
+> DropDownOpening cancellation
+> IsDropDownOpen
+> Candidate trigger state
+```
+
+键盘行为:
+
+- 弹层打开时,按键优先交给 `CandidateList.HandleKeyDown()`。
+- `Escape` 取消候选并关闭弹层。
+- `Enter` 在弹层打开时提交当前候选。
+- `F4` 切换弹层打开状态。
+- 弹层关闭时,`Down` 可打开弹层,除非该按键被 XY focus 导航占用。
+
+Form 集成以 `Value` 作为表单值。`NotifyValidateStatus` 将 Form 校验状态映射为 `Status=Error/Warning/Default`,Form feedback 控件传递给内部 `MentionTextArea`。
+
+## 5. 视觉与主题模型
+
+Mentions 的默认视觉由 `MentionsTheme.axaml` 和内部 TextArea 主题协作:
+
+| 主题或资源 | 职责 |
+| --- | --- |
+| `MentionsTheme.axaml` | 根模板、`MentionTextArea`、popup、loading、候选列表和 MentionsToken 资源绑定。 |
+| `TextAreaTheme.axaml` | 输入表面、placeholder、清除按钮、Form feedback、多行高度和状态视觉。 |
+| `CandidateList` 主题 | 候选项容器、选中项、键盘导航和提交取消事件。 |
+| `PopupHostToken` | popup 阴影、圆角和 anchor margin。 |
+| `MentionsToken` | popup 内容 padding、候选项高度和最小宽度。 |
+
+输入框本体不由 Mentions 自己重写边框和文本 presenter,而是通过内部 `MentionTextArea` 复用 TextArea 体系。Mentions 的控件级 Token 只服务候选弹层,不承载文本高度、输入边框、状态颜色或 Form feedback。
+
+## 6. 控件家族或集成关系
+
+Mentions 属于 Data Entry 文本输入控件家族,与 LineEdit/TextArea 共享输入表面、状态、尺寸、清除按钮和 Form 语义。
+
+集成关系:
+
+- `MentionTextArea` 继承 `TextArea`,复用多行输入能力,并增加 trigger scan、过滤值同步和候选插入。
+- `Popup` 提供候选弹层宿主,可通过 `ShouldUseOverlayPopup` 选择 overlay 宿主。
+- `CandidateList` 提供候选项展示、键盘导航、提交和取消。
+- `AsyncSearchLoadCoordinator` 协调异步加载、跳过过期结果、取消和超时。
+- `IFormItemAware` / `IFormItemFeedbackAware` 将 `Value`、校验状态和 feedback 接入 Form。
+- `MentionsToken` 定义候选弹层尺寸相关主题值。
+
+## 7. 兼容性不变量
+
+维护 Mentions 时必须保持以下不变量:
+
+- `Value` 必须继续与内部 `MentionTextArea.Text` 双向同步。
+- `DefaultValue` 只在初始化且 `Value` 为空时写入。
+- `TriggerPrefix` 默认值为 `["@"]`,当前触发识别只支持单字符前缀。
+- 触发扫描不能跨越空白或控制字符。
+- `OptionsSource` 集合变化必须同步到内部缓存和候选视图。
+- `OptionsAsyncLoader` 存在时必须优先走异步加载,并通过 `OptionsLoaded` 报告结果。
+- `AsyncLoadDebounce` 变化必须释放旧 timer,避免重复填充。
+- 重新套用模板必须解绑旧 `MentionTextArea`、旧 `Popup` 和旧 `CandidateList` 事件。
+- 弹层打开期间的可见性、启用状态和窗口失活必须关闭弹层。
+- 候选提交必须通过 `MentionTextArea.InsertMentionOption()` 写回文本,保持 undo/redo 快照和 caret/selection 语义。
+- MentionsToken 不承载输入文本、过滤值、候选数据、loading、Form 状态或交互状态。
+
+## 8. 专项模型
+
+### 8.1 候选过滤模型
+
+Mentions 将 `OptionsSource` 缓存为 `List`,再根据 `FilterValue` 构造当前候选视图。默认过滤器是 contains。`FilterValueSelector` 存在时使用 selector 返回值;否则按 `Header`、`Value`、`Key` 的顺序选择过滤文本。
+
+过滤过程通过 `_filterInAction` 和 `_cancelRequested` 避免重入时生成过期视图。刷新完成后,候选列表自动选中第一项。
+
+### 8.2 异步加载模型
+
+`OptionsAsyncLoader` 接收当前过滤值和 cancellation token。`AsyncSearchLoadCoordinator` 负责超时、取消、跳过过期结果和错误状态归一。成功结果会写入 `OptionsSource` 并继续走 `PopulateComplete()`;失败结果只通过 `OptionsLoaded` 通知业务层。
+
+### 8.3 候选插入模型
+
+提交候选时,控件优先使用 `option.Value`,其次使用 `option.Header`。插入逻辑回溯到当前 mention 触发符位置,选中触发符到当前 caret 的文本片段,然后按 `Split` 或空格规则生成插入文本。
+
+`Split` 为单字符时,插入文本以 split 包裹;未设置 split 时,插入文本默认以空格分隔,避免 mention 与相邻普通文本粘连。
+
+### 8.4 Popup 定位模型
+
+`Placement=Bottom` 映射为 `PlacementMode.BottomEdgeAlignedLeft`,`Placement=Top` 映射为 `PlacementMode.TopEdgeAlignedLeft`。打开候选弹层时,控件根据触发字符 bounds 和 text presenter bounds 计算 popup 偏移,使候选弹层对齐当前触发位置。
+
+## 9. 文档导航与验证策略
+
+关联文档:
+
+- [Mentions 桌面版实现原理](implementation.md)
+- [Mentions Token 设计](token.md)
+- [Mentions Changelog](changelog.md)
+- [LineEdit Token 设计](../line-edit/token.md)
+
+验证策略:
+
+| 层次 | 验证内容 |
+| --- | --- |
+| Public API | `Value`、`TriggerPrefix`、候选数据、异步 loader、弹层、输入表面、Form 和事件契约。 |
+| 状态 | 触发符识别、过滤值、弹层打开/关闭、loading、disabled、readonly、error、warning、auto-size。 |
+| AXAML/Theme | `PART_TextArea`、`PART_Popup`、`PART_CandidateList`、loading、popup shadow、SizeType、StyleVariant。 |
+| Token | `PopupContentPadding`、`OptionHeight`、`MinPopupWidth` 的默认值、生成 TokenKind、Gallery Token 表和主题引用。 |
+| Gallery | 走查基础、variant、异步加载、自定义触发符、disabled/read-only、placement、status、auto-size 和 clear 示例。 |
+| 回归测试 | `MentionsShowCasePageTests`、相关控件测试和 `git diff --check`。 |
diff --git a/docs/controls/desktop/data-entry/mentions/token.md b/docs/controls/desktop/data-entry/mentions/token.md
new file mode 100644
index 000000000..e24e88a30
--- /dev/null
+++ b/docs/controls/desktop/data-entry/mentions/token.md
@@ -0,0 +1,89 @@
+# Mentions Token 设计
+
+本文档定义 `AtomUI.Desktop.Controls.MentionsToken` 的专属语义、分类、使用范围和兼容边界。控件 Token 的通用分层、命名、计算、Theme Variables 边界和预设色规则见 [AtomUI 控件 Token 设计规范](../../../../engineering/control-token-guidelines.md)。Mentions 整体架构见 [Mentions 桌面版架构设计](overview.md),内部实现原理见 [Mentions 桌面版实现原理](implementation.md),设计和契约变化记录见 [Mentions Changelog](changelog.md)。
+
+## 1. 定位
+
+MentionsToken 是 Mentions 的组件级 Token scope,只描述候选弹层的结构尺寸。输入框本体由内部 `MentionTextArea` 复用 TextArea / AddOnDecoratedBox / SharedToken 体系;候选列表项的选择、hover、disabled 和文本状态由 CandidateList 主题处理。
+
+MentionsToken 不承载以下状态:
+
+- `Value`、`FilterValue`、`TriggerPrefix`、`OptionsSource`、`OptionsAsyncLoader` 等数据状态。
+- `IsDropDownOpen`、`IsLoading`、`IsReadOnly`、`IsAutoSize`、`Status` 等运行状态。
+- 候选项 selected、hover、disabled、commit、cancel 等交互状态。
+- Popup 当前 offset、placement、实际高度或异步加载结果。
+
+## 2. Token 分类
+
+### 2.1 候选弹层 padding Token
+
+- `PopupContentPadding`
+
+该 Token 控制 `PopupFrame` 内部 padding,并参与 `MaxPopupHeight` 计算。默认值为 `SharedToken.UniformlyPaddingXXS / 2` 的四边等距 padding。
+
+### 2.2 候选项高度 Token
+
+- `OptionHeight`
+
+该 Token 表示候选项行高基准,默认值为 `SharedToken.ControlHeight`。Mentions 使用它结合 `DisplayCandidateCount` 计算候选弹层最大高度。
+
+### 2.3 候选弹层最小宽度 Token
+
+- `MinPopupWidth`
+
+该 Token 控制候选弹层最小宽度,默认值为 `120`。实际弹层宽度仍受 popup placement、候选内容和布局约束影响。
+
+## 3. 控件专项模型中的 Token 使用
+
+MentionsToken 使用路径:
+
+```text
+SharedToken
+ ↓
+MentionsToken
+ ↓
+MentionsTheme.axaml
+ ↓
+PopupFrame + MaxPopupHeight + CandidateList viewport
+```
+
+主题使用点:
+
+- `ItemHeight="{atom:MentionsTokenResource OptionHeight}"`
+- `PopupContentPadding="{atom:MentionsTokenResource PopupContentPadding}"`
+- `MinPopupWidth="{atom:MentionsTokenResource MinPopupWidth}"`
+
+`MaxPopupHeight` 不是 Token。它由 `ItemHeight`、`DisplayCandidateCount` 和 `PopupContentPadding` 在控件实例上计算,属于运行时布局结果。
+
+## 4. 控件家族影响
+
+MentionsToken 只影响 Mentions 候选弹层,不直接影响 AutoComplete、Select、TreeSelect、ComboBox 或普通 TextArea。虽然这些控件也有 popup padding、option height 和 min popup width 语义,但它们各自拥有独立 Token scope。
+
+调整 MentionsToken 时必须评估:
+
+- `MentionsTheme.axaml`
+- `MentionsShowCase` 的 Design Token 表
+- `MentionsShowCasePageTests`
+- 候选弹层 loading、候选列表可视高度和 popup 最小宽度
+
+## 5. 兼容性要求
+
+MentionsToken 属于 Mentions 主题契约。即使 `MentionsToken` 是 internal 类型,生成的 `MentionsTokenKind`、AXAML resource 使用点和 Gallery Token 表已经形成稳定依赖。
+
+Token 变更要求:
+
+- 不擅自重命名或删除 `PopupContentPadding`、`OptionHeight`、`MinPopupWidth`。
+- 不把实例数据、过滤状态、loading 状态、候选选择状态或 Form 状态迁移为 Token。
+- 不在 MentionsToken 中复制 TextArea 输入边框、字体、清除按钮或校验状态 Token。
+- 不把 `DisplayCandidateCount` 变成 Token;它是实例级行为属性。
+- 需要破坏性变更时,必须先说明影响范围并获得授权。
+
+## 6. 验证策略
+
+| 改动类型 | 验证要求 |
+| --- | --- |
+| 修改 `PopupContentPadding` | 验证 popup 内边距、loading 布局、候选项裁剪和 `MaxPopupHeight`。 |
+| 修改 `OptionHeight` | 验证候选项高度、键盘选中项可见性和 `DisplayCandidateCount` 对弹层高度的影响。 |
+| 修改 `MinPopupWidth` | 验证短候选、长候选、Top/Bottom placement 和 Gallery 示例弹层宽度。 |
+| 删除或重命名 Token | 默认不允许;如获授权,需同步 AXAML 引用、生成文件、Gallery Token 表和控件文档。 |
+| 文档改动 | 运行 `git diff --check`,检查文档链接存在。 |
diff --git a/docs/controls/desktop/data-entry/overview.md b/docs/controls/desktop/data-entry/overview.md
index b87be0e64..34408947c 100644
--- a/docs/controls/desktop/data-entry/overview.md
+++ b/docs/controls/desktop/data-entry/overview.md
@@ -13,6 +13,10 @@
- [SearchEdit 桌面版架构设计](search-edit/overview.md)
- [SearchEdit 桌面版实现原理](search-edit/implementation.md)
- [SearchEdit Changelog](search-edit/changelog.md)
+- [Mentions 桌面版架构设计](mentions/overview.md)
+- [Mentions 桌面版实现原理](mentions/implementation.md)
+- [Mentions Token 设计](mentions/token.md)
+- [Mentions Changelog](mentions/changelog.md)
- [NumericUpDown 桌面版架构设计](numeric-up-down/overview.md)
- [NumericUpDown 桌面版实现原理](numeric-up-down/implementation.md)
- [NumericUpDown Token 设计](numeric-up-down/token.md)
diff --git a/src/AtomUI.Desktop.Controls/Input/Themes/TextAreaDecoratedBoxTheme.axaml b/src/AtomUI.Desktop.Controls/Input/Themes/TextAreaDecoratedBoxTheme.axaml
index bf38dc34e..1a2eb0e46 100644
--- a/src/AtomUI.Desktop.Controls/Input/Themes/TextAreaDecoratedBoxTheme.axaml
+++ b/src/AtomUI.Desktop.Controls/Input/Themes/TextAreaDecoratedBoxTheme.axaml
@@ -67,6 +67,9 @@
+