Hermes Agent 36967370fd SwiftBricks: Bricks JSON UI framework native Swift/SwiftUI implementation
- Core: Schema (Codable), Store, EventBus, RPC, Engine, I18n
- Controls: Text, Title1-6, Label, Input, Textarea, Number, Date, Button, Select
  VBox, HBox, ScrollPanel, DynamicColumn, Tabular, Form, InlineForm,
  TabView, Menu, PopupWindow, Html, Image, UrlWidget
- Renderer: BricksView (main entry), ControlRenderer (recursive dispatch)
- 30+ widget types, 9 bind actiontypes
- Form validation (required/minlength/maxlength/min/max/email/number/pattern)
- i18n with multi-language JSON files
- 18 tests covering schema parsing, store, i18n, events
2026-06-21 12:12:03 +08:00

118 lines
3.2 KiB
Swift
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

import Foundation
import Combine
import SwiftUI
/// Bricks binds
/// widget
@MainActor
public final class BricksStore: ObservableObject {
/// widget: widgetId value
@Published public var values: [String: Any] = [:]
/// : formId {fieldName: value}
@Published public var formValues: [String: [String: String]] = [:]
/// Tabular: tabularId rows
@Published public var tableData: [String: [[String: Any]]] = [:]
/// Tabular: tabularId selectedIndex
@Published public var selectedRows: [String: Int] = [:]
///
@Published public var popups: [String: PopupState] = [:]
///
@Published public var collapsedMenus: Set<String> = []
private var cancellables = Set<AnyCancellable>()
public init() {}
// MARK: -
public func getValue(id: String) -> Any? {
values[id]
}
public func setValue(id: String, value: Any?) {
if let value {
values[id] = value
} else {
values.removeValue(forKey: id)
}
}
// MARK: -
public func getFormField(formId: String, field: String) -> String {
formValues[formId]?[field] ?? ""
}
public func setFormField(formId: String, field: String, value: String) {
if formValues[formId] == nil {
formValues[formId] = [:]
}
formValues[formId]?[field] = value
}
public func getFormValues(formId: String) -> [String: String] {
formValues[formId] ?? [:]
}
public func setFormValues(formId: String, data: [String: String]) {
formValues[formId] = data
}
public func clearForm(formId: String) {
formValues[formId]?.keys.forEach { key in
formValues[formId]?[key] = ""
}
}
// MARK: -
public func setTableData(id: String, rows: [[String: Any]]) {
tableData[id] = rows
}
public func getTableData(id: String) -> [[String: Any]] {
tableData[id] ?? []
}
public func selectRow(tabularId: String, index: Int) {
selectedRows[tabularId] = index
}
public func getSelectedRow(tabularId: String) -> Int? {
selectedRows[tabularId]
}
public func getSelectedRowData(tabularId: String) -> [String: Any]? {
guard let idx = selectedRows[tabularId],
let rows = tableData[tabularId],
idx >= 0, idx < rows.count else { return nil }
return rows[idx]
}
// MARK: -
public func openPopup(id: String, schema: ControlSchema, options: PopupOptions) {
popups[id] = PopupState(schema: schema, options: options, isOpen: true)
}
public func closePopup(id: String) {
popups.removeValue(forKey: id)
}
public func isPopupOpen(id: String) -> Bool {
popups[id]?.isOpen ?? false
}
}
///
public struct PopupState {
public let schema: ControlSchema
public let options: PopupOptions
public var isOpen: Bool
}