Appearance
界面构建示例
这个示例展示一个完整但不拥挤的动态界面。它重点演示:
- 顶部
Tabs,避免小屏被左侧导航挤压。 Group的 12 栅格布局。- 响应式布局:短组件
layout = { span = 6, lg = 3 },小屏最多两列,大屏最多四列。 - 长组件、说明、图片、提示、折叠面板统一
layout = { span = 12 }。 - 组件联动:
visibleWhen和disabledWhen。 - 参数读取:
onUIChanged(values)和UICurrentValue。
lua
local ui = require("ui_builder")
------------------------------------------------------------
-- 1. 选项数据
------------------------------------------------------------
local modeItems = {
{ key = "auto", label = "自动", description = "按默认策略运行" },
{ key = "manual", label = "手动", description = "手动控制流程" },
{ key = "debug", label = "调试", description = "输出更多日志" },
}
local projectItems = {
{ key = "hexide", label = "HexIDE" },
{ key = "uitest", label = "UITEST" },
{ key = "legacy", label = "Legacy", isDisabled = true },
}
local fruitItems = {
{ key = "apple", label = "苹果" },
{ key = "banana", label = "香蕉" },
{ key = "orange", label = "橙子" },
}
local priorityItems = {
{ key = "low", label = "低" },
{ key = "normal", label = "普通" },
{ key = "high", label = "高" },
}
------------------------------------------------------------
-- 2. 表单组件
------------------------------------------------------------
local taskName = ui.createInput("taskName", "任务名称", "请输入任务名称", "默认任务")
taskName.Input.variant = "bordered"
taskName.Input.isClearable = true
taskName.Input.layout = { span = 6, lg = 3 }
local count = ui.createNumberInput("count", 1, "数量", 0, 100, 1, "1~100")
count.NumberInput.variant = "bordered"
count.NumberInput.layout = { span = 6, lg = 3 }
local mode = ui.createSelect("mode", "auto", "运行模式", modeItems)
mode.Select.variant = "bordered"
mode.Select.layout = { span = 6, lg = 3 }
local project = {
Autocomplete = {
name = "project",
label = "项目",
placeholder = "搜索项目",
defaultSelectedKey = "hexide",
variant = "bordered",
isClearable = true,
items = projectItems,
layout = { span = 6, lg = 3 },
}
}
local enableFeature = {
Switch = {
name = "enableFeature",
title = "启用功能",
isSelected = true,
color = "primary",
layout = { span = 6, lg = 3 },
}
}
local debugMode = {
Switch = {
name = "debugMode",
title = "调试模式",
isSelected = false,
color = "warning",
layout = { span = 6, lg = 3 },
}
}
local enableLog = ui.createCheckbox("enableLog", "记录日志", true)
enableLog.Checkbox.layout = { span = 6, lg = 3 }
local priority = ui.createRadioGroup("priority", "normal", "优先级", priorityItems)
priority.RadioGroup.orientation = "horizontal"
priority.RadioGroup.layout = { span = 12 }
local fruits = ui.createCheckboxGroup("fruits", {"apple"}, "水果选择", fruitItems)
fruits.CheckboxGroup.orientation = "horizontal"
fruits.CheckboxGroup.layout = { span = 12 }
local speed = ui.createSlider("speed", 50, "运行速度", 0, 100, 1)
speed.Slider.color = "primary"
speed.Slider.showTooltip = true
speed.Slider.layout = { span = 12 }
local range = ui.createSlider("range", {20, 80}, "有效范围", 0, 100, 1)
range.Slider.color = "warning"
range.Slider.showTooltip = true
range.Slider.layout = { span = 12 }
range.Slider.disabledWhen = {
field = "enableFeature",
equals = false,
}
local debugRemark = ui.createInput("debugRemark", "调试备注", "调试模式开启后显示", "")
debugRemark.Input.variant = "bordered"
debugRemark.Input.layout = { span = 12 }
debugRemark.Input.visibleWhen = {
field = "debugMode",
equals = true,
}
------------------------------------------------------------
-- 3. 展示组件
------------------------------------------------------------
local tip = ui.createAlert("提示", "这是一个完整动态 UI 示例,所有布局都按小屏优先设计。", "primary")
tip.Alert.layout = { span = 12 }
local warning = ui.createAlert("注意", "Div / Group / P / Tabs / Accordion 不产生值,内部输入组件正常取值。", "warning")
warning.Alert.layout = { span = 12 }
local chips = {
Div = {
className = "flex flex-wrap items-center gap-2",
layout = { span = 12 },
item = {
{
ui.createChip("在线", "success", "flat"),
ui.createChip("响应式", "primary", "bordered"),
ui.createChip("可联动", "warning", "flat"),
}
}
}
}
local desc = {
P = {
text = "短组件使用 span=6, lg=3;长组件、说明和展示区域使用 span=12,避免窄屏挤压。",
className = "text-sm leading-6 text-default-500 break-words",
layout = { span = 12 },
}
}
local image = ui.createImage("https://placehold.co/640x240", true, "预览图片", "640", "240")
image.Image.radius = "sm"
image.Image.layout = { span = 12 }
local divider = ui.createDivider("horizontal")
divider.Divider.layout = { span = 12 }
------------------------------------------------------------
-- 4. 分组和容器
------------------------------------------------------------
local baseGroup = {
Group = {
title = "基础参数",
description = "短组件小屏最多两列,大屏最多四列。",
direction = "grid",
columns = 12,
gap = 4,
item = {
{ taskName, count, mode, project },
{ enableFeature, debugMode, enableLog },
{ debugRemark },
{ speed },
{ range },
},
layout = { span = 12 },
}
}
local choiceGroup = {
Group = {
title = "选择参数",
direction = "grid",
columns = 12,
gap = 4,
item = {
{ priority },
{ fruits },
},
layout = { span = 12 },
}
}
local statusCard = {
Div = {
className = "rounded-small border border-default-200 bg-default-50 p-4",
layout = { span = 12 },
item = {
{ tip },
{ warning },
{ chips },
{ desc },
{ image },
},
}
}
------------------------------------------------------------
-- 5. Accordion 折叠面板
------------------------------------------------------------
local accName = ui.createInput("accName", "折叠输入", "请输入", "")
accName.Input.variant = "bordered"
accName.Input.layout = { span = 6, lg = 3 }
local accSlider = ui.createSlider("accSlider", 30, "折叠滑块", 0, 100, 1)
accSlider.Slider.layout = { span = 12 }
local accTip = {
P = {
text = "Accordion 收起不会销毁内部组件,值会保留。",
className = "text-sm text-default-500",
layout = { span = 12 },
}
}
local accordion = ui.createAccordion({
ui.createTab("输入项", {
{ accTip },
{ accName },
}),
ui.createTab("滑块项", {
{ accSlider },
}),
})
accordion.Accordion.variant = "splitted"
accordion.Accordion.selectionMode = "multiple"
accordion.Accordion.defaultSelectedKeys = {"输入项"}
accordion.Accordion.layout = { span = 12 }
------------------------------------------------------------
-- 6. Tabs 页面
------------------------------------------------------------
local overviewTab = ui.createTab("总览", {
{ statusCard },
})
local formTab = ui.createTab("表单", {
{ baseGroup },
{ divider },
{ choiceGroup },
})
local advancedTab = ui.createTab("高级", {
{ accordion },
})
local mainTabs = ui.createTabs({
overviewTab,
formTab,
advancedTab,
}, "top", true)
mainTabs.Tabs.variant = "underlined"
mainTabs.Tabs.color = "primary"
mainTabs.Tabs.fullWidth = true
mainTabs.Tabs.layout = { span = 12 }
------------------------------------------------------------
-- 7. 构建并启动 UI
------------------------------------------------------------
ui.buildUI({ mainTabs }, 1)
StartUI()
------------------------------------------------------------
-- 8. 取值
------------------------------------------------------------
function onUIChanged(values)
print("========== UI 当前值 ==========")
print("taskName =", values.taskName)
print("count =", values.count)
print("mode =", values.mode)
print("project =", values.project)
print("enableFeature =", values.enableFeature)
print("debugMode =", values.debugMode)
print("enableLog =", values.enableLog)
print("priority =", values.priority)
print("speed =", values.speed)
print("debugRemark =", values.debugRemark)
print("accName =", values.accName)
print("accSlider =", values.accSlider)
if values.fruits ~= nil then
for index, value in ipairs(values.fruits) do
print("fruit", index, value)
end
end
end
function printCurrentValues()
print("当前任务:", UICurrentValue.taskName)
print("当前速度:", UICurrentValue.speed)
print("当前项目:", UICurrentValue.project)
end