# Selene XAML Vocabulary 指南

Selene XAML 由两层组成：MS-XAML-2017 Profile 1 定义 XML 到 object、member、
markup extension 的 infoset 映射规则（namespace、property element、`x:Name`
等）；`urn:selene:xaml:ui` 中的 Selene UI vocabulary 在此基础上定义具体类型，
lower 为 typed tree、binding 和 ECS reconciliation。本文定义后者，并说明这些名称与
WPF、WinUI、Avalonia、NoesisGUI 和 Web UI 概念之间的关系。Profile 1 的精确规范
覆盖和偏差以 [Profile 1 conformance matrix](ms-xaml-conformance.md) 为准。

本文中的"组件"泛指可以出现在 XAML 中的 `ui:` 类型。只有
`ui:Component` 专指可注册、可复用的 Selene 组件。

Selene UI vocabulary 由三组生态概念构成：CSS 定义布局（box、Flex、Grid），XAML 定义数据和
状态（Binding、ResourceDictionary、VisualState），React/Web 定义结构组合（If、keyed
collection、slot projection）。名称使用 XAML PascalCase 表面，语义服从来源生态的成熟模型。

表格中 `~` 表示近似概念，`—` 表示该生态没有直接的同层类型。

本文用以下等级描述 Selene 类型与 XAML 参考物之间的一致程度（与 Web 参考物
差异显著时在单元格单独标注）：

| 等级 | 含义 |
| --- | --- |
| 高 | 用途和核心标记模型都接近，已有经验可以直接迁移 |
| 中 | 解决相同问题，但属性系统、生命周期或运行时语义有明显差异 |
| 低 | 只有局部概念可用于理解，不应期待 API 或行为兼容 |
| 无直接对应 | Selene 组合了多个生态概念，或提供了自己的结构能力 |

这些等级不表示 MS-XAML conformance。

## Layout

布局容器（`View`、`Flex`、`Grid`、`UniformGrid`、`Overlay`、`ScrollView`）
及 box model、alignment、positioning、`ClipToBounds` 和滚动模型定义在
[Selene Layout Vocabulary](layout-vocabulary.md)。布局属性的 canonical 名称（如
`JustifyContent`、`AlignItems`、`AlignSelf`、`HorizontalAlignment`、
`VerticalAlignment`）也以该文档为准。

## Text & Typography

| 类型 | Selene 定义 | XAML 参考物 | Web 参考物 | 一致程度 | 关键差异与取舍 |
| --- | --- | --- | --- | --- | --- |
| `Text` | 文本 Entity；支持纯文本属性、排版属性及由 `Span` 组成的富文本 | `TextBlock` | text element | 高 | 没有完整 typography、inline 类型层级和文本编辑模型。固有尺寸由 layout engine 按约束宽度和换行规则 measure。 |
| `Span` | `Text` 内的富文本片段，也保留 Entity 以支持动态 binding | `Span` / `Run` | `<span>` | 高 | runtime 会把片段汇总成父 `Text` 的稳定 span 列表；片段可覆盖文本、字体、颜色、字重、行高、字距和下划线。 |

Canonical typography members：

| Member | 类型 | 取值 | 默认 |
| --- | --- | --- | --- |
| `Text` | `String` | — | — |
| `Color` | `Color` | — | — |
| `FontFamily` | `String` | — | — |
| `FontSize` | `Double` | — | — |
| `FontWeight` | enum | `Thin` `ExtraLight` `Light` `Normal` `Medium` `SemiBold` `Bold` `ExtraBold` `Black` `ExtraBlack` | `Normal` |
| `TextAlign` | enum | `Left` `Center` `Right` | `Left` |
| `TextWrapping` | enum | `NoWrap` `Wrap` | `NoWrap` |
| `TextOverflow` | enum | `Clip` `Ellipsis` | `Clip` |
| `LineHeight` | `Double` | > 0 | `1.0` |
| `LetterSpacing` | `Double` | 有限的逻辑像素值 | `0.0` |

`FontWeight` 生成 1–1000 数值字重，参与测量、shaping 与栅格缓存。
`LineHeight` 是字体大小的倍数；`LetterSpacing` 在 Cosmic Text shaping 后添加到
glyph advance。根 Text 与 Span 的 range styles 由同一个文本块布局，因此测量、
换行、ellipsis、对齐和两个渲染后端使用完全相同的 advances。

## Image

| 类型 | Selene 定义 | XAML 参考物 | Web 参考物 | 一致程度 | 关键差异与取舍 |
| --- | --- | --- | --- | --- | --- |
| `Image` | 由 `Source` 加载图像，支持 `Fit`、`Tint`、`SourceRegion`、`Sampler`、`Opacity`、`Brightness`、`Saturation`、`DropShadow` 和 `atlas.json#region` | `Image` + presentation properties | `<img>` + `opacity`/`filter` | 高 | `Tint`、`SourceRegion` 和呈现属性支持 literal、Binding 和 VisualState；`Sampler` 是 Bevy 风格的 asset load setting，只接受常量 `Default`、`Nearest`、`Linear`。同一路径首次加载的 sampler 随缓存的 `ImageHandle` 共享，Binding 与 VisualState Setter 会被拒绝。`SourceRegion="x y width height"` 服务于外部 spritesheet metadata，空 Binding 清除裁剪。Selene `atlas` 可导入 canonical Selene、Aseprite 和 TexturePacker JSON。显式 `SourceRegion` 与 named atlas region 在同一 Image node 上互斥。 |

`Opacity` 是所有可视节点共有且向子树累乘的 XAML/Web 常用属性，范围为
`0..1`。`Brightness` 和 `Saturation` 是 Image 专用、非负且无上限的倍率，默认
`1`；`Saturation="0"` 产生灰度，`Brightness="0"` 可生成剪影。两个后端都在
Tint 之后使用同一公式：

```text
rgb = mix(luma(rgb), rgb, Saturation) * Brightness
alpha = alpha * inherited Opacity
```

`DropShadow` 使用图片最终 fit 后的透明轮廓，而不是 Image 的矩形布局边界。字符串
格式为 `x-offset y-offset blur-radius color`；也可使用 typed object/resource：

```xml
<ResourceDictionary>
  <DropShadow x:Key="PortraitShadow"
              Offset="0,8" BlurRadius="12" Color="#00000099" />
</ResourceDictionary>

<Image Source="monster.png"
       Opacity="0.8" Brightness="0.72" Saturation="0.65"
       DropShadow="{StaticResource PortraitShadow}" />
```

offset 和 blur 使用逻辑像素，blur 必须非负。`DropShadow` 不参与布局，也不同于
容器的 `BoxShadow`：前者采样图片 alpha，后者沿节点圆角矩形轮廓绘制。

## Vector Path

`PathIcon` 是单色 UI 符号，不是完整 SVG document host。`Data` 使用 SVG/XAML
Path Markup 的 `M/m`、`L/l`、`Q/q`、`C/c`、`Z/z` 子集；生成器会把相对坐标
归一化为绝对的 typed commands，并在 XAML 源位置拒绝未知命令、空 geometry、
非有限坐标和运行时 Binding。闭合 contour 使用 `Color` 填充；
`StrokeWidth > 0` 时闭合与开放 contour 都使用同一颜色描边。

| Member | 类型 | 取值 | 默认 |
| --- | --- | --- | --- |
| `Data` | path literal | `M/m L/l Q/q C/c Z/z` | required |
| `Color` | `Color` | literal、StaticResource、Binding、VisualState | `#ffffff` |
| `StrokeWidth` | `Double` | `>= 0`；literal、Binding、VisualState | `0` |
| `Stretch` | enum | `None` `Fill` `Uniform` | `Uniform` |

`Uniform` 按 authored geometry bounds 等比适配 content box；剩余空间由
`HorizontalAlignment` 和 `VerticalAlignment` 决定。曲线展开、凹多边形填充和
圆连接宽描边在 core 中生成 backend-independent triangle lists，raylib 与 WebGPU
消费同一几何。复杂多色 SVG、gradient、mask、filter、text 和动画仍应在构建阶段
栅格化为 PNG/Atlas。

只有图标的按钮必须提供 accessible name。Selene 采用 XAML 生态的 attached member
`AutomationProperties.Name`，并把它投影到 core `a11y`：

```xml
<Button AutomationProperties.Name="返回">
  <PathIcon Data="M 18 4 L 6 12 L 18 20"
            Width="24" Height="24"
            Color="#ffffff" StrokeWidth="2"
            Stretch="Uniform" />
</Button>
```

## Button

| 类型 | Selene 定义 | XAML 参考物 | Web 参考物 | 一致程度 | 关键差异与取舍 |
| --- | --- | --- | --- | --- | --- |
| `Button` | 可交互、可聚焦的多子节点容器；事件名映射到 runtime 注册的 action | `Button` | `<button>` | 中 | 交互和焦点由 ECS stores 与 systems 驱动，action 接收 `XamlActionContext`；没有 routed event、command、control template 和框架级样式系统。 |

## Focus & Navigation

可视节点共享以下 focus vocabulary：

| Member | 语义 |
| --- | --- |
| `Focusable` | 节点是否进入直接 focus 和方向导航候选集；`Button` 默认为 `true` |
| `TabIndex` | Next/Previous 顺序；负值保留直接 focus，但跳过顺序导航 |
| `FocusScope` | 节点挂载且 active 时成为 focus scope；最晚激活的 scope 限制所有导航候选 |
| `AutoFocus` | 作为最近祖先 scope 的初始焦点；重复模板中的第一个有效节点获选 |
| `ui:Navigation.Up/Down/Left/Right` | `Auto` 使用几何搜索，`Stop` 消费该方向，其他值解析为同一 mounted View 的 stable key |

方向导航优先采用显式连接，随后按与请求方向的夹角及距离做几何搜索。

## Identity & Actions

`x:Name` 是可视节点唯一的 authored identity。它建立 namescope 中的 stable key，供
VisualState `TargetName`、方向导航、热重载状态恢复和 action route 使用。普通可视节点
不再提供平行的 `Id`、`Target` 或 `Watch` vocabulary；对象引用只在明确声明为
`EntityReference` 的专用 member 上使用 `{x:Reference ...}`。

可视节点使用 React props 风格、XAML PascalCase 的 action member：

| Member | 触发边界 | 状态 |
| --- | --- | --- |
| `OnClick` | primary pointer 完成 click，或 focused Button 被设备无关 Activate 导航动作激活 | Implemented |
| `OnPointerDown` | pointer 在命中节点上按下；action payload 保持当前 item key，不暴露 backend pointer object | Implemented |
| `OnPointerEnter` / `OnPointerLeave` | hover identity 进入或离开节点 | Implemented |
| `OnFocus` / `OnBlur` | focus identity 进入或离开节点 | Implemented |
| `OnMount` | 节点 Entity 首次成功提交到 mounted View；replace 保留节点时不重复触发 | Implemented |

action member 只接受 literal 值，不接受 Binding 或 converter。

## Brush & Appearance

所有可视节点使用 XAML 生态通行的 `Background`、`BorderBrush`、
`BorderThickness` 和 `CornerRadius`。`Background` 是类型化 `Brush`：颜色文本是
`Solid` Brush 简写，也可以通过 property element 或 `StaticResource` 传递完整
`LinearGradientBrush`。

```xml
<Flex BorderBrush="#E19D4C"
      BorderThickness="7,2,2,7"
      CornerRadius="30,12,30,12">
  <Flex.Background>
    <LinearGradientBrush StartPoint="0.2,0" EndPoint="0.8,1">
      <GradientStop Offset="0.1" Color="#4D2C20" />
      <GradientStop Offset="0.5" Color="#815432" />
      <GradientStop Offset="0.9" Color="#211411" />
    </LinearGradientBrush>
  </Flex.Background>
</Flex>
```

| Member | 多值顺序 | 简写规则 |
| --- | --- | --- |
| `BorderThickness` | 左、上、右、下 | 单值→四边；双值→水平/垂直 |
| `CornerRadius` | 左上、右上、右下、左下 | 单值→四角；双值→两组对角 |

公开 surface 只保留 `BorderBrush`、`BorderThickness` 和 `CornerRadius`。

`LinearGradientBrush` 接受不同的归一化 `StartPoint`/`EndPoint` 和至少两个按
`Offset` 非递减排列的 stop。首个 stop 之前与末个 stop 之后分别钳制为首尾颜色；
相同 offset 可表达硬边过渡，渐变轴不需要覆盖 box 的四个角。核心层把每段渐变裁剪
并三角化为遵循节点 `CornerRadius` 的共享彩色几何，使 raylib 和 WebGPU 得到相同
结果。径向渐变、重复渐变和混合模式仍会在生成阶段带源位置拒绝。完整 Brush 可以
作为 `StaticResource`，也可以由 VisualState Setter 原子替换；Host 在替换或卸载时
释放其拥有的 UI material。

`BoxShadow` 字符串格式为 `x-offset y-offset blur-radius spread-radius color`，
多层以分号分隔。offset、blur、spread 使用逻辑像素，blur 必须非负。

```xml
<Flex BoxShadow="0 0 0 3 #E19D4C40; 0 28 90 0 #070403AD" />
```

首版只提供 outer box shadow。完整 list 可作为 `StaticResource` 或由 Binding / VisualState
Setter 整体替换。Object form 使用 `BoxShadow.Layers` 与 `ShadowLayer`：

```xml
<BoxShadow x:Key="ElevatedPanel">
  <ShadowLayer XOffset="0" YOffset="0" BlurRadius="0"
               SpreadRadius="3" Color="#E19D4C40" />
  <ShadowLayer XOffset="0" YOffset="28" BlurRadius="90"
               SpreadRadius="0" Color="#070403AD" />
</BoxShadow>
```

## Data Binding

| 类型 | Selene 定义 | XAML 参考物 | Web 参考物 | 一致程度 | 关键差异与取舍 |
| --- | --- | --- | --- | --- | --- |
| `Binding` | `{ui:Binding Path=..., Converter={x:Static package:function}}` 从当前 typed ViewModel scope 读取字段，可经静态一元函数转换后写入属性 | `{Binding}` | reactive projection ~ | 高（OneWay） | 只有 source-to-target；ViewModel 是生成 package 公开的 ECS component。调用方修改 component 后显式调用完整、根字段、collection 或 keyed-item refresh API。生成 runtime 不做自动属性通知、record reconstruction 或 Array defensive copy。converter 是任意 `moonbit:` package 的公开函数，生成器不注册对象或复制 MoonBit 类型检查。没有 runtime `DataContext` 继承对象、TwoWay/OneTime mode、ConvertBack、fallback、validation 或 ElementName。 |
| `TemplateBinding` | `{ui:TemplateBinding ...}` 从当前组件 parameter map 读取值 | `{TemplateBinding}` | — | 中 | 指向 `ui:Parameter`，并非 templated parent 的 dependency property；只承担组件模板内的轻量 parameter 投影。 |

`Path` 支持 `.`（当前值）、字段路径和数组索引。`Converter` 使用
`{x:Static moonbit:package/name}`，由 MoonBit 编译器检查函数签名。

内置 converter（`KKKIIO/selene/xaml_view`）：

| 函数 | 说明 |
| --- | --- |
| `bool_not` | 布尔取反 |
| `option_is_some` / `option_is_none` | Option 判断 |
| `string_is_empty` / `string_is_not_empty` | 字符串判空 |
| `array_is_empty` / `array_is_not_empty` | 数组判空 |
| `bool_select`、`number_compare`、`equal_to` | 组合原语（多参数，需包装为一元函数） |

## Structural Control Flow

| 类型 | Selene 定义 | XAML 参考物 | Web 参考物 | 一致程度 | 关键差异与取舍 |
| --- | --- | --- | --- | --- | --- |
| `ItemsControl` | 用 `ItemsSource` 数组和 `ItemTemplate` 重复生成内容；`KeyPath` 可读取稳定 String/Int key | `ItemsControl` | list rendering ~ | 高 | 保留熟悉的 `ItemsSource` + `ItemTemplate` 模型。完整 collection refresh 与 ViewModel replace 按 key 局部调和并保留 item host Entity，重复 key 在 presentation mutation 前失败；没有直接 `Items`、ItemsPanel、collection view、选择、虚拟化或隐式 observable collection。省略 `KeyPath` 时使用数组索引。 |
| `If` | 根据 `Condition` 的 truthy 值实例化 `Then` 或 `Else` 子树 | trigger / `Visibility` ~ | conditional rendering | 中 | 条件控制 instance tree 结构，dependency-directed refresh 与完整 replace 只替换发生变化的分支。XAML 框架常通过 `Visibility`、trigger 或 converter 保留节点；Selene 选择显式结构节点以适配 ECS 生命周期。 |
| `DataTemplate` | 保存一组可按 item data 实例化的 `Content`，当前由 `ItemsControl.ItemTemplate` 使用 | `DataTemplate` | template / JSX fragment ~ | 高 | item 成为模板内容的 data scope；可在 `Resources` 中声明编译期资源，没有 `DataType`、template selector、hierarchical template 或任意框架对象的隐式模板查找。 |

## Components

| 类型 | Selene 定义 | XAML 参考物 | Web 参考物 | 一致程度 | 关键差异与取舍 |
| --- | --- | --- | --- | --- | --- |
| `Component` | 可注册模板的根类型，声明 QName、parameters 和 content；实例拥有隔离的内部 namescope | `UserControl` / custom control | component / custom element | 中 | generator 以精确 namespace URI + type name 注册并在 ViewIR lowering 前展开；没有 CLR 类继承、code-behind、style selector 或 control-template 查找。 |
| `Parameter` | 声明组件输入的名称、类型、默认值和 required 约束 | dependency property ~ | props / attributes | 中 | 支持 String、Bool、Int、Double、Val、Color 和通用 Data；在组件边界做转换和校验。 |
| `Slot` | 在组件模板中声明默认或命名投影点，并可包含 fallback 子树 | `ContentPresenter` ~ | `<slot>` / `children` | 高（Web）/中（XAML） | 调用方以 attached `ui:Slot` 选择投影点；投影内容保持调用方 data 和 namescope。 |
| Generated View | XAML 生成的 View package，通过 `moonbit:` QName 引用 | `UserControl` | React component ~ | 中 | 编译期 package import；单一 typed ViewModel input。 |
| Custom View | 手写 MoonBit package，实现 `mount`/`replace`/`component_plugin` | `UserControl` / custom control ~ | React component / custom element ~ | 中低 | caller-owned Entity root、ECS plugin 生命周期，非 OOP 继承。 |

`Component` / `Parameter` / `Slot` 已作为 source-directory 的编译期组合边界实现。
generator 先注册目录中的 `Component` declaration，再解析普通 View；parameter literal、
Binding 或默认值通过 `TemplateBinding` 投影到模板，命名 slot 和默认 slot 在 lowering
前展开。模板内部 `x:Name` 使用实例前缀形成隔离 namescope，projected child 保持调用方
data scope 和 namescope。缺少 required parameter、重复 QName、未知 parameter type、
多根模板和无效 slot 会在生成阶段失败。component declaration 不单独生成 runtime package；
展开后的普通 typed tree 继续使用既有 Host reconciliation。

跨 package View component（Generated View、Custom View）仍是独立的运行时组合边界。

父 XAML 用 `moonbit:` QName 引用跨 package View：

```xml
<Flex xmlns="urn:selene:xaml:ui"
      xmlns:inventory="moonbit:game/generated/ui_views/inventory_tab">
  <inventory:InventoryTabView
      x:Name="inventoryTab"
      ViewModel="{Binding Path=inventory}"
      Active="{Binding Path=inventoryActive}" />
</Flex>
```

组件 element QName 直接提供 View package 与 View type，compiler 据此生成对子 package
的直接 import 和生命周期调用。Moon 检查 child API、`ViewModel` 实参类型与 package
依赖环，无需额外 component manifest。父 View 拥有组件 placeholder Entity 和 child
instance：首次 mount 创建，replace 传递新 ViewModel，`Active=false` 仅隐藏且保留 child
local state；销毁 parent root 会连同 placeholder subtree 一起销毁 child root。每个 child
package 使用独立 `ViewHost` record，namescope 与 event routing 隔离。同一 child package
可由不同 parent stable key 挂载多次，各实例拥有独立 root Entity 与 namescope。

Custom View package 实现以下 ABI：

```moonbit nocheck
CustomView::mount(root, view_model)
CustomView::replace(root, view_model)
component_plugin(app)
```

父 View 在 caller-owned root 上投影普通 View 属性，包括尺寸、box model、flex、position、
`Active`、`ClipToBounds`、focus 与 action。Custom View 自行决定内部状态表示，
`component_plugin` 注册所需的 ECS 系统。显示状态由 caller 直接设置通用
`Visibility`；generated parent 的 `unmount` 由共享 `ViewHost` 按 Entity hierarchy
递归清理，不要求 Custom View 扩展 ABI；Custom View 契约仍不包含 `unmount`、
rollback 或恢复回调。

当前跨 package View component 是静态节点，只接受一个 typed `ViewModel` input。
`If` / `ItemsControl` 内动态 component instance 与 projected child content 属于后续
reconciliation 工作。

## Visual States

| 类型 | Selene 定义 | XAML 参考物 | Web 参考物 | 一致程度 | 关键差异与取舍 |
| --- | --- | --- | --- | --- | --- |
| `VisualStateGroup` | 一组互斥状态，包含 `States`、`Transitions` 和可 binding 的 `Current` | `VisualStateGroup` | state model ~ | 高 | 没有 `Current` 的 group 由 Host 的 Normal、Hovered、Focused、Pressed、Disabled 状态驱动，业务 group 由 typed `Current` binding 驱动；没有可替换的 VisualStateManager。Avalonia 更接近以 pseudo-class/style 表达状态。 |
| `VisualState` | 命名状态及其有序 setter 列表 | `VisualState` | state/class ~ | 高 | Selene 直接叠加 property values；没有 Storyboard、StateTrigger 或任意 animation object tree。多个 group 按声明顺序形成确定的覆盖层。 |
| `Setter` | 将 `Value` 写到 owner 或 `TargetName` 指向的节点属性 | visual-state `Setter` | style assignment ~ | 高（WinUI）/中（WPF、Noesis） | 目标必须位于正确 namescope，属性必须属于 runtime 支持的 ECS 投影；`Value` 可使用编译期 `StaticResource`，没有样式 selector 和完整 dependency property precedence。 |
| `Transition` | 用 `From`、`To`、`Duration`、`Delay`、`Easing` 描述状态切换 | `VisualTransition` | CSS transition | 中 | Color、Double 和同单位 layout value 可插值，其他值离散切换；支持 Linear、EaseIn、EaseOut、EaseInOut，并可从中断时当前值继续。省去 Storyboard、keyframe 和自定义 easing 对象。 |

## Resources

| 类型 | Selene 定义 | XAML 参考物 | Web 参考物 | 一致程度 | 关键差异与取舍 |
| --- | --- | --- | --- | --- | --- |
| `ResourceDictionary` | 带 `Source`、`MergedDictionaries` 和 `x:Key` 条目的编译期资源容器 | `ResourceDictionary` | CSS custom property ~ | 中 | 支持 `Color`、`x:String`、`x:Double`、`x:Int32`、`LinearGradientBrush`、`BoxShadow` 和 `DropShadow` 条目。外部字典在编译期读取并纳入生成 source header；运行时不保留资源查找表。 |
| `StaticResource` | `{StaticResource Key}` 从当前词法资源作用域读取设计 token 或完整 Brush | `{StaticResource}` | — | 中 | 在 ViewIR lowering 前替换成带来源信息的常量；标量使用引用位置 span，Brush 保留其结构化定义 span。没有 `DynamicResource` 或运行时 ambient lookup。 |

`BoxShadow` 与 `DropShadow` 的 dictionary object form 都和各自的属性字符串使用
同一个 typed grammar。

## XAML Language Layer

以下项目属于解析和对象映射层。infoset 中存在某个 directive，不等于 runtime
具备完整 CLR/WPF 构造语义。

| 语法或名称 | 来源 | Profile 1 行为 | Runtime 边界 |
| --- | --- | --- | --- |
| object element 与 property element | MS-XAML 对象映射 | `<ui:Text>` 创建 object node；`<ui:ItemsControl.ItemTemplate>` 设置已注册 member | 只能使用 schema registry 中的精确类型和 member；未知 non-ignorable 名称报错 |
| attached member | MS-XAML 对象映射 | `ui:Grid.Row`、`ui:Grid.Column`、`ui:Slot` 必须由 owner schema 声明为 attached | 按各 vocabulary 的 Implemented/Planned 状态投影，没有通用 getter/setter metadata |
| `x:Name` | 标准 `x:` directive | 进入 namescope，并作为唯一 authored node identity | runtime 用它解析导航、VisualState target、action route 和 name-restored reload state |
| `x:Class` | 标准 `x:` directive | 只允许在 document root，决定公开 generated View type 名称 | 保留 MoonBit generated type 命名，不提供 CLR class construction/inheritance |
| `x:Static` | 标准 `x:` markup extension | 在 `Binding.Converter` 中引用 `moonbit:` namespace 的 package-level 函数 | 生成静态函数调用；不构造 CLR static member object，也没有 runtime converter registry |
| `x:Key` | 标准 `x:` directive | 只允许作为 `ResourceDictionary` 直属标量条目的资源键 | 编译期解析后不会进入 runtime object graph |
| `x:Items` | 标准 `x:` directive | parser 接受并保存在 infoset | 没有通用 list/dictionary 构造；重复数据 UI 使用 `ui:ItemsControl` |
| `x:Initialization` | 标准 `x:` directive | parser 接受 text/object values 并保存在 infoset | 没有 CLR 初始化或任意对象构造协议 |
| `x:PositionalParameters` | 标准 `x:` directive | parser 接受并保存在 infoset | 没有通用 constructor invocation；markup extension 自己解释位置参数 |
| `{x:Null}` | 标准 `x:` markup extension | 求值为 `XamlData::Null` | 可用于 Profile 1 支持的 value/member；没有完整 nullable type metadata |
| `{x:Reference name}` | 标准 `x:` markup extension | 名称在正确的组件或调用方 namescope 中解析 | EntityReference 成员在构造后连接；不会向任意 member 暴露通用对象引用 |
| `{x:Type prefix:Name}` | 标准 `x:` markup extension | 使用 namespace map 和 schema registry 校验类型 | 结果是 symbolic type name，不创建通用 runtime `XamlType` 对象 |
| `xml:space` | XML namespace | 支持 `default` 和 `preserve`，控制 text normalization | 只影响 parser 生成的 text nodes |
| `mc:Ignorable` | XAML Markup Compatibility | 忽略列出的设计时 namespace 中的 attribute/element | 未实现 `ProcessContent`、`AlternateContent`、preservation 等完整 MC vocabulary |

Selene 使用标准 `x:` namespace：
`http://schemas.microsoft.com/winfx/2006/xaml`。`ui:` namespace 是
`urn:selene:xaml:ui`。前缀名称可以变化，namespace URI 决定身份。

## Selene 的总体取舍

- **ECS-native runtime**：View package 通过 `selene/xaml_view` 创建 Entity 并写入 Selene UI stores，公开 View 身份始终是根 Entity；focus auto-reveal policy 留在 `xaml_view`，`ui` 只提供通用几何 primitive。
- **生态职责分工**：CSS layout + XAML data/state/resources + React/Web structural composition；XAML PascalCase 只统一书写表面，不改变各概念的来源语义。
- **CSS layout、XAML clipping**：尺寸、box、alignment、Flex、Grid 和 positioning 对标 CSS 与 Taffy；容器裁剪使用 `ClipToBounds`，滚动由 `ScrollView` 独占；布局模型详见 [Selene Layout Vocabulary](layout-vocabulary.md)。
- **显式数据通知**：游戏代码修改生成 package 公开的 ViewModel ECS component，再调用 dependency-directed 或完整 refresh；idle frame 不轮询或深比较 ViewModel。
- **局部结构调和**：`If` 只替换变化分支，keyed `ItemsControl` 只替换受影响 item；文件 reload 采用验证后整体替换，并恢复 host 与按名称保存的状态。
- **编译期设计 token**：标量 `ResourceDictionary` 与 `StaticResource` 在 ViewIR 前折叠；运行时不承担资源优先级、动态查找或样式 selector。
- **View package 组件与状态系统**：跨 package component 使用一个 typed ViewModel input；生成 View 具有独立 namescope，Custom View 管理自己的内部状态；setter overlays 和有限 transition 覆盖声明式游戏 UI 的核心需求，避免引入 CLR reflection、完整 dependency property、运行时 style 和 Storyboard 子系统。

## 官方参考资料

- [MS-XAML-2017 Xaml Schema Information Set](https://learn.microsoft.com/en-us/openspecs/microsoft_domain_specific_languages/ms-xaml-2017/b9b26f10-5e6c-4e93-b82a-198f1d11d3ab)
- [MS-XAML `x:` Schema](https://learn.microsoft.com/en-us/openspecs/microsoft_domain_specific_languages/ms-xaml/8b8949ad-2d26-4ec5-913e-1df1ebd5e78c)
- [Selene Layout Vocabulary](layout-vocabulary.md)
- [WPF Data Templating Overview](https://learn.microsoft.com/en-us/dotnet/desktop/wpf/data/data-templating-overview)
- [WinUI Data Binding in Depth](https://learn.microsoft.com/en-us/windows/apps/develop/data-binding/data-binding-in-depth)
- [WinUI `VisualState.Setters`](https://learn.microsoft.com/en-us/windows/windows-app-sdk/api/winrt/microsoft.ui.xaml.visualstate.setters?view=windows-app-sdk-1.8)
- [Avalonia `ItemsControl`](https://docs.avaloniaui.net/controls/data-display/collections/itemscontrol)
- [Avalonia Style Classes and Pseudoclasses](https://docs.avaloniaui.net/docs/styling/style-classes)
- [NoesisGUI Architecture](https://www.noesisengine.com/docs/Gui.Core.Architecture.html)
- [NoesisGUI Binding](https://www.noesisengine.com/docs/Gui.Core.Binding.html)
- [CSS Flexbox](https://developer.mozilla.org/en-US/docs/Web/CSS/Guides/Flexible_box_layout/Basic_concepts)
- [Web Components Templates and Slots](https://developer.mozilla.org/en-US/docs/Web/API/Web_components/Using_templates_and_slots)
- [React Conditional Rendering](https://react.dev/learn/conditional-rendering)
