Skip to content

界面构建示例

这个示例展示一个完整但不拥挤的动态界面。它重点演示:

  • 顶部 Tabs,避免小屏被左侧导航挤压。
  • Group 的 12 栅格布局。
  • 响应式布局:短组件 layout = { span = 6, lg = 3 },小屏最多两列,大屏最多四列。
  • 长组件、说明、图片、提示、折叠面板统一 layout = { span = 12 }
  • 组件联动:visibleWhendisabledWhen
  • 参数读取: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