iPaas.Controls
1.0.7
dotnet add package iPaas.Controls --version 1.0.7
NuGet\Install-Package iPaas.Controls -Version 1.0.7
<PackageReference Include="iPaas.Controls" Version="1.0.7" />
<PackageVersion Include="iPaas.Controls" Version="1.0.7" />
<PackageReference Include="iPaas.Controls" />
paket add iPaas.Controls --version 1.0.7
#r "nuget: iPaas.Controls, 1.0.7"
#:package iPaas.Controls@1.0.7
#addin nuget:?package=iPaas.Controls&version=1.0.7
#tool nuget:?package=iPaas.Controls&version=1.0.7
iPaas.Controls
<img src="src/iPaas.Controls/Assets/icon.png" width="72" alt="" />
一个 Avalonia 设计系统与组件库,语义与 shadcn-svelte 一一对应: 同样的 token 名字、同样的组件命名与变体、同样的浅色/深色两套配色,只是把「网页」换成了「桌面」。
接上这一行,平台自带控件(Button、TextBox、CheckBox…)就已经是 shadcn 的外观:
<Application.Styles>
<ipaas:Theme />
</Application.Styles>
快速开始
包发在 CyberStone 的 BaGet 源上,先让 NuGet 认识它(放在解决方案旁边,或写进用户级 NuGet.Config 一次到位):
<?xml version="1.0" encoding="utf-8"?>
<configuration>
<packageSources>
<clear />
<add key="nuget.org" value="https://api.nuget.org/v3/index.json" />
<add key="CyberStone" value="https://baget.cyber-stone.com/v3/index.json" />
</packageSources>
</configuration>
dotnet add package iPaas.Controls
跟预览版用 dotnet add package iPaas.Controls --prerelease。要求 .NET 10 与 Avalonia 12.1 以上。
不想先写代码可以直接看画廊:每个 vX.Y.Z 的 Release
上都挂着 iPaasControlsDemo.exe(win-x64,自包含单文件,双击即跑,不用装 .NET),旁边是同版本的
.nupkg 与带 SourceLink 的 .snupkg。
接上开头那一行 <ipaas:Theme />(它一次带入三层内容:设计 token、浅色/深色两套语义色、以及所有控件主题,
含 Button、TextBox、CheckBox 这些平台控件),库里的控件补齐平台没有的部分,第一个界面大概长这样:
<ipaas:Card Width="360" HorizontalAlignment="Left">
<StackPanel Spacing="24">
<ipaas:CardHeader>
<ipaas:CardTitle Content="Deployment" />
<ipaas:CardDescription Content="The last one is still rolling out." />
</ipaas:CardHeader>
<ipaas:CardContent>
<StackPanel Spacing="12">
<StackPanel Spacing="6">
<Label Content="Environment" />
<TextBox PlaceholderText="production" />
</StackPanel>
<StackPanel Orientation="Horizontal" Spacing="8">
<ipaas:Badge Content="Healthy" />
<ipaas:Badge Variant="Outline" Content="iPaas" />
</StackPanel>
</StackPanel>
</ipaas:CardContent>
<ipaas:CardFooter>
<StackPanel Orientation="Horizontal" Spacing="8">
<Button Content="Deploy" />
<Button Classes="outline" Content="Cancel" />
</StackPanel>
</ipaas:CardFooter>
</StackPanel>
</ipaas:Card>
组件画廊(src/iPaas.Controls.Demo)里有同样的内容,而且是活的:目录最前面的 Install、Get started、
Styles、Theme 四页就是这份文档,每个示例都能当场看到它自己的 AXAML 源码。
样式
每个控件都按 shadcn 的写法给变体与尺寸:类名和附加属性两条路等价,前者短、后者编译期可发现。
<Button Classes="secondary" Content="Secondary" />
<Button Classes="destructive" Content="Destructive" />
<Button Classes="outline" Content="Outline" />
<Button Classes="ghost" Content="Ghost" />
<Button Classes="link" Content="Link" />
<Button Classes="sm" Content="小" />
<Button Classes="lg" Content="大" />
<Button Classes="icon" Content="+" />
<Button ipaas:ButtonAssist.Variant="Outline" ipaas:ButtonAssist.Size="Sm" Content="取消" />
谁赢,三条规则覆盖全部:
| 实例上写的 | 某个控件自己写的 Height/Padding/FontSize/Background 压过下面所有样式 |
| 类 | sm/lg 这类尺寸类指向 token 阶梯的某一档,所以密度旋钮怎么动,它都还是 32 |
| 旋钮 | ControlDefaults 改的是控件主题读的引用型 token;主题全用 DynamicResource 读,所以在屏幕上已经显示出来的控件也会跟着变 |
内缩跟谁走
一个控件要么按密度(跟着控件高度变),要么按某一档(固定)。同一条规则在仓库里踩过好几次
(侧栏分组标题、导航触发器、输入框、表格列头),现在写进了 docs/design-system.md 第 7 节:高度走密度的
控件,内缩与字号也必须走密度;固定高度的行里,纵向内缩只会挤掉文字;而"装裱"类内缩(比如输入框组的
addon)只缩朝外那一侧。
主题
颜色是两个互相独立的旋钮,合起来只有一套语义角色:
ControlDefaults.BaseColor = ThemeBaseColor.Slate; // 基色:22 种(Neutral…Rose)
ControlDefaults.Mode = ThemeMode.Dark; // 浅色 / 深色 / 跟随系统
// 也可以只给一个窗口:不动库级默认
window.RequestedThemeVariant = ThemeVariant.Dark;
- Mode 选哪本字典:浅色与深色是同一批角色的两本字典(
Theming/Themes/Light.axaml、Dark.axaml), 控件只写角色名(BackgroundBrush、PrimaryBrush…),由 variant 决定读哪本。它是 Avalonia 的 variant, 所以同一个窗口里也能局部切(ThemeVariantScope)。 - 基色重指两本字典背后的调色板:
Neutral是 shadcn 发布的原始数值,其余 21 种按「角色 → Tailwind 色阶」派生,浅色与深色一起改,所以两者正交、不会互相覆盖。 - 不受基色影响的角色:
destructive、success、warning、info与遮罩——警告永远是警告的颜色。
派生规则(Theming/ThemePalette.cs,完整表格见 docs/design-system.md 第 4 节):
| 角色 | 浅色 | 深色 |
|---|---|---|
| background / card / popover | 白 | 950 / 900 / 900 |
| foreground | 950 | 50 |
| primary(灰系基色) | 900 | 600 |
| primary(彩色基色) | 600(挑不到 AA 标签时往深走一档) | 600(同左) |
| primary foreground | 50,或按面挑的那支深墨 | 同左 |
| secondary / muted / accent | 100 | 800 |
| muted foreground | 600(按面挑,还可能要再深一档;shadcn 的 500 在 muted 底上只有 4.35:1) | 400 |
| border / input | 200 | 白 10% / 15% |
| ring | 400 | 500 |
| sidebar | 50 | 900 |
两支墨不写死档位:primary foreground 与 muted foreground 在它自己要压的那张面上按亮度挑(亮面翻成
深墨,中亮度的面挑不出 AA 就让面自己走一档),AccessibilityTests 走遍 22 个基色 × 浅深两套盯着;
warning 那支琥珀的浅色档也在数据里改深了一档(2.94:1 → 4.92:1)。
另外两个旋钮动的是几何——密度与圆角,和上面两个颜色旋钮各管各的:
ControlDefaults.Size = ControlSize.Sm; // 密度:Xs / Sm / Md / Lg / Xl
ControlDefaults.Radius = ControlRadius.Xs; // 圆角族:None / Xs / Sm / Md / Lg / Full
设计系统
四层,自下而上,每层只依赖下一层:
| 层 | 位置 | 内容 |
|---|---|---|
| 1 基础 token | Theming/Tokens/Primitives.axaml |
间距、圆角、字号字重、控件高度、图标尺寸、动效、阴影、遮罩层级 |
| 2 语义 token | Theming/Tokens/Semantics.axaml |
控件主题唯一允许引用的名字:ControlHeight、ControlPadding、ControlCornerRadius… |
| 3 调色板 | Theming/Palettes/*.axaml |
Tailwind 22 组色阶(Blue500Brush、Slate200…) |
| 4 语义颜色 | Theming/Themes/Light.axaml、Dark.axaml |
shadcn 的角色色:BackgroundBrush、PrimaryBrush、RingBrush、SidebarAccentBrush… |
颜色以 OKLCH 撰写(shadcn 的原始格式),由 build/GenerateThemeTokens.ps1 转成 Avalonia 可读的
Color/SolidColorBrush 并生成 C# 表,所以 XAML 与运行期两条路径不会漂移。
组件
命名与属性尽量沿用 shadcn-svelte,Avalonia 已有的控件直接复用(只换外观),shadcn 有而 Avalonia 没有的
以 iPaas.Controls 下的同名控件补齐。
已实现
| shadcn-svelte | 这里的写法 |
|---|---|
| button | Button + Classes="secondary/destructive/outline/ghost/link"、sm/lg/icon |
| button-group | ipaas:ButtonGroup |
| badge | ipaas:Badge(Variant 或同名类) |
| card | ipaas:Card、CardHeader、CardTitle、CardDescription、CardAction、CardContent、CardFooter |
| alert | ipaas:Alert、AlertTitle、AlertDescription(Variant="Destructive",可带 Icon) |
| avatar | ipaas:Avatar(Source 或首字母内容)、AvatarFallback |
| input / textarea | TextBox、TextBox Classes="textarea" |
| label | Label |
| checkbox / radio / switch / slider / progress / separator / skeleton / spinner | CheckBox、RadioButton、ipaas:Switch、Slider(横 / 竖)、ProgressBar、ipaas:Separator、ipaas:Skeleton、ipaas:Spinner |
| kbd | ipaas:Kbd、KbdGroup |
| empty | ipaas:Empty、EmptyHeader、EmptyMedia、EmptyTitle、EmptyDescription、EmptyContent |
| toggle / toggle-group | ipaas:Toggle(Variant、Size)、ipaas:ToggleGroup |
| select | ipaas:Select(ComboBox 的主题版) |
| tabs | ipaas:Tabs + TabItem(Variant="Line" 为下划线样式) |
| accordion / collapsible | ipaas:Accordion(Mode="Single" 单开)、ipaas:Collapsible |
| table | ipaas:Table、TableHeader、TableBody、TableFooter、TableRow Columns="2*,*,Auto"、TableHead、TableCell、TableCaption |
| dropdown-menu / context-menu / menubar | MenuFlyout + MenuItem + Separator(Button.Flyout、ContextMenu 属性均可用)、ipaas:Menubar |
| tooltip | ToolTip.Tip="…" |
| popover / hover-card | ipaas:Popover(Trigger + IsOpen)、ipaas:HoverCard(悬停打开) |
| breadcrumb | ipaas:Breadcrumb、BreadcrumbList、BreadcrumbItem、BreadcrumbLink、BreadcrumbPage、BreadcrumbSeparator、BreadcrumbEllipsis |
| pagination | ipaas:Pagination、PaginationContent、PaginationItem、PaginationLink、PaginationPrevious、PaginationNext、PaginationEllipsis |
| dialog / alert-dialog / sheet / drawer | ipaas:Dialog、ipaas:AlertDialog、ipaas:Sheet Side="Right"、ipaas:Drawer(Classes="compact" 把卡片内缩收到 Xs 档) |
其余组件
以画廊为准:一个组件一页,65 页组件,外加开头四页文档。除上表之外还有:
| 分组 | 控件 |
|---|---|
| 输入 | Calendar(平台控件的皮肤)/ ipaas:RangeCalendar、ipaas:DatePicker / ipaas:RangeDatePicker、ipaas:Cascader、ipaas:TreeSelect、ipaas:InputGroup / ipaas:InputOtp / ipaas:NativeSelect、ipaas:NumberInput(数字字段:右侧两个扁按钮叠成一个方块(列宽 = 字段高),提交时把值夹进量程、按 ValueFormat 重写文本)、ipaas:HexInput(hex 字段,右侧 … 开一个 ipaas:HexEditor 的十六进制编辑器)、ipaas:FileInput / ipaas:FolderInput(路径字段:右侧按钮开平台的文件 / 文件夹选择器;Picker 是可替换的钩子)、ipaas:ImagePicker(图片字段:名字前是缩略图,点缩略图看大图)、ipaas:Checklist(勾选组:多选,勾选即选中,竖排或横排自动换行) |
| 展示 | ipaas:Item、DataGrid(平台的表格,本包换皮肤)、ipaas:AutoScrollTable(滚动窗:MaxRows 从窗口头上裁、最新一行滚入视图)、ipaas:Knob(读数可走 ReadoutOf 模板)、ipaas:Led(状态灯,Content 是标注,LabelPlacement 放上下左右)、ipaas:Meter / ipaas:Voltmeter / ipaas:Ammeter(仪表盘:Minimum/Maximum 是量程、Value 是当前值、Unit 跟在读数后面、读数可走 ReadoutOf 模板;只有显示部分)、ipaas:LcdDisplay(七段读数:Digits 个位、ValueFormat 位小数、超量程用告警墨色、没有值时是横杠)、ipaas:TextDisplay(文本件:值 → 静态文本 → 值→文本映射 → 小数位,Unit 跟在后面,颜色可走值→色,TextAlignment 管对齐)、ipaas:Clock / ipaas:Uptime(随时间的读数:每秒刷新,TimeSource 是给测试的缝;Clock 的格式写网页那套 YYYY/MM/DD/HH/hh/mm/ss 记号,Uptime 三种形状与网页一致)、ipaas:ImageDisplay(图片件:Stretch 是 fit、CornerRadius 是形状、没图时显示 FallbackText)、ipaas:Progress(ProgressBar 的派生类型,指示条按值取色)、ipaas:ParameterTable + ipaas:Parameter(配方 / 参数表:一行一个设定值,IsWriteProtected 一把锁管整张表,行自己的 IsWritable 管自己)、ColorPicker / ColorView / ColorSpectrum(同上,平台的调色控件换皮肤;ColorPicker 的触发行是可编辑的 hex 字段,敲 #297aa0 回车即提交,点色板照旧开弹层) |
| 报警 | ipaas:AlarmList(一行一条,含 TimestampFormat / EmptyText)、ipaas:AlarmBanner(页顶一条:最严重的那个 + 等确认的条数 + 一键确认)、ipaas:AlarmPanel(灯屏:一台设备一盏灯,未确认戴一圈环)——数据都是 ipaas:Alarm(Severity / State / Source / Message / Timestamp)。三个控件都只报告确认动作(Acknowledged / AcknowledgeRequested),不改 State:确认是给报警服务器的命令 |
| 导航 | ipaas:Command(+ ipaas:CommandDialog)、ipaas:Carousel、ipaas:NavigationMenu、ipaas:Tabs、ipaas:Accordion / ipaas:Collapsible |
| 浮层 | ipaas:Dialog / ipaas:AlertDialog / ipaas:Sheet / ipaas:Drawer、ipaas:Popover / ipaas:HoverCard、ipaas:Toaster、ipaas:Menubar |
| 布局 | ipaas:Sidebar、ipaas:ResizablePanelGroup / ResizablePanel / ResizableHandle、ipaas:ScrollArea、ipaas:AspectRatio、ipaas:Table(以及卡片里的 flat 类) |
| 其他 | ipaas:Field 家族(Field/FieldLabel/FieldError…)、ipaas:TreeView、ipaas:DragDropAssist(见 drag-drop.md)、ipaas:Spinner、ipaas:Empty |
ipaas:Led / ipaas:LcdDisplay / ipaas:Meter / ipaas:Progress 都能用 ValueBrushSelector(值 → 画刷)按值取色;Led 另有 Value / ValueBrush,关灯取同一支色的 30% 档;Blink.IsBlinking / Blink.Brush(附加属性)给 Led / LcdDisplay / Meter 一个闪烁的开关与颜色——闪不闪是页面的判断,库只管效果(相位是缝,Blink.PinnedPhase 能钉住,测试与截图都读得到)。
读数**拼不成"小数位 + 后缀"**时用 ipaas:Knob / ipaas:Meter 的 ReadoutOf(值 → 词,{value}℃ 那类模板的语法归调用方);ipaas:TextDisplay 的对齐走 TextAlignment(居中的读数不用自己拼 TextBlock)。
三个不做的:chart 不做组件(shadcn 的 chart 是 recharts 封装,Avalonia 侧请用 LiveCharts / ScottPlot,
配色取 Chart1..5Brush);pythonBlock 不做(脚本引擎是宿主的事,外壳件用 Select / TextBlock / Button 拼);
form 不做 schema 绑定(错误态走 Field.IsInvalid)。
更细的(每个控件为什么长这样、踩过哪些坑)在 docs/design-system.md 第 7 节的坑表里; 组件清单、还没做的事与开工流程见 docs/roadmap.md。
图标
控件自己的 chrome(勾、箭头、叉、加载圈…)用的是随包发布的几何图形:Icons.g.cs,由
build/GenerateIcons.ps1 从 docs/reference/icons 下的 Lucide SVG 生成,绘图方式是 Lucide 的描边方式。
应用侧要整套图标时用 Lucide.Avalonia(本包已依赖):
<lucide:LucideIcon Kind="Star" Size="16" />
仓库结构
| 目录 | 内容 |
|---|---|
src/iPaas.Controls |
库本体:Theming/ 是设计系统,Controls/<名字>/ 是每个组件的控件类与主题 |
src/iPaas.Controls.Demo |
组件画廊,顶部四个下拉框就是上面那四个旋钮 |
src/iPaas.Controls.Tests |
xunit + Avalonia.Headless:token、控件几何、状态、遮罩层与画廊渲染 |
build/ |
token 与图标生成脚本 |
docs/reference |
token、色板与图标的原始数据(来自 shadcn-svelte 与 Lucide) |
dotnet build iPaas.Controls.slnx
dotnet test src/iPaas.Controls.Tests/iPaas.Controls.Tests.csproj
dotnet run --project src/iPaas.Controls.Demo/iPaas.Controls.Demo.csproj
构建前先关掉正在运行的画廊:它会锁住
src/iPaas.Controls.Demo/bin/…里的iPaas.Controls.dll,于是解决方案里的依赖项目拷不进去、构建失败(测试项目引用了画廊,所以dotnet test也会受影响)。临时绕过:先dotnet build src/iPaas.Controls/iPaas.Controls.csproj, 再dotnet test src/iPaas.Controls.Tests/iPaas.Controls.Tests.csproj -p:BuildProjectReferences=false。
许可
MIT,见 LICENSE。设计语言来自 shadcn-svelte(MIT),图标来自 Lucide(ISC), 出处与改动见 NOTICE。
| Product | Versions Compatible and additional computed target framework versions. |
|---|---|
| .NET | net10.0 is compatible. net10.0-android was computed. net10.0-browser was computed. net10.0-ios was computed. net10.0-maccatalyst was computed. net10.0-macos was computed. net10.0-tvos was computed. net10.0-windows was computed. |
-
net10.0
- Avalonia (>= 12.1.2)
- Avalonia.Controls.ColorPicker (>= 12.1.2)
- Avalonia.Controls.DataGrid (>= 12.1.2)
- Avalonia.Themes.Simple (>= 12.1.2)
- Lucide.Avalonia (>= 0.2.23)
NuGet packages
This package is not used by any NuGet packages.
GitHub repositories
This package is not used by any popular GitHub repositories.
| Version | Downloads | Last Updated |
|---|---|---|
| 1.0.7 | 283 | 10/14/2026 |