{"id":24851921,"url":"https://github.com/holistic-apps-ltda/declarativeui","last_synced_at":"2025-10-14T22:31:09.481Z","repository":{"id":39874489,"uuid":"471541985","full_name":"Holistic-Apps-LTDA/DeclarativeUI","owner":"Holistic-Apps-LTDA","description":"A library to develop UI declaratively in Swift. ","archived":false,"fork":false,"pushed_at":"2022-05-24T00:31:50.000Z","size":388,"stargazers_count":4,"open_issues_count":0,"forks_count":0,"subscribers_count":1,"default_branch":"main","last_synced_at":"2025-01-30T08:33:26.000Z","etag":null,"topics":["declarative","declarative-programming","declarative-ui","declarativeui","swift","ui-components"],"latest_commit_sha":null,"homepage":"","language":"Swift","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/Holistic-Apps-LTDA.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2022-03-18T23:14:49.000Z","updated_at":"2023-01-31T01:58:22.000Z","dependencies_parsed_at":"2022-08-20T19:50:25.189Z","dependency_job_id":null,"html_url":"https://github.com/Holistic-Apps-LTDA/DeclarativeUI","commit_stats":null,"previous_names":[],"tags_count":10,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Holistic-Apps-LTDA%2FDeclarativeUI","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Holistic-Apps-LTDA%2FDeclarativeUI/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Holistic-Apps-LTDA%2FDeclarativeUI/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Holistic-Apps-LTDA%2FDeclarativeUI/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/Holistic-Apps-LTDA","download_url":"https://codeload.github.com/Holistic-Apps-LTDA/DeclarativeUI/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":236528932,"owners_count":19163730,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["declarative","declarative-programming","declarative-ui","declarativeui","swift","ui-components"],"created_at":"2025-01-31T14:27:31.690Z","updated_at":"2025-10-14T22:31:03.930Z","avatar_url":"https://github.com/Holistic-Apps-LTDA.png","language":"Swift","readme":"# DeclarativeUI\nA library to develop UI declaratively in Swift.\n\n- [Requirements](#requirements)\n- [Installation](#installation)\n- [Usage](#usage)\n\n## Requirements\n\n| Platform | Minimum Swift Version | Installation | Status |\n| --- | --- | --- | --- |\n| iOS 11.0+ | 5.0 | [CocoaPods](#cocoapods), [Carthage](#carthage), [Swift Package Manager](#swift-package-manager) | Partially Tested |\n\n## Installation\n\n### CocoaPods\n\n[CocoaPods](https://cocoapods.org) is a dependency manager for Cocoa projects. For usage and installation instructions, visit their website. To integrate DeclarativeUI into your Xcode project using CocoaPods, specify it in your `Podfile`:\n\n```ruby\npod 'DeclarativeUUI', '~\u003e 0.0.10'\n```\n\n### Carthage\n\n[Carthage](https://github.com/Carthage/Carthage) is a decentralized dependency manager that builds your dependencies and provides you with binary frameworks. To integrate DeclarativeUI into your Xcode project using Carthage, specify it in your `Cartfile`:\n\n```ogdl\ngithub \"Holistic-Apps-LTDA/DeclarativeUI\" ~\u003e 0.0.10\n```\nIn terminal run:\n\n```ogdl\ncarthage update --use-xcframeworks\n```\n\n### Swift Package Manager\n\nThe [Swift Package Manager](https://swift.org/package-manager/) is a tool for automating the distribution of Swift code and is integrated into the `swift` compiler. \n\nOnce you have your Swift package set up, adding DeclarativeUI as a dependency is as easy as adding it to the `dependencies` value of your `Package.swift`.\n\n```swift\ndependencies: [\n    .package(url: \"https://github.com/Holistic-Apps-LTDA/DeclarativeUI.git\", .upToNextMajor(from: \"0.0.10\"))\n]\n```\n\n## Usage\n\nA demo app is available in the DemoApp folder for querying the usage of library components.\n\n### ViewModel\n\n```swift\nenum DemoInteractionEvents {\n    case rowSelect(DataObject)\n    case iconTap\n}\n\nimport DeclarativeUI\n\nfinal class DemoViewModel: DeclarativeViewModel\u003cVoid, Error\u003e {\n\n    // MARK: Attributes\n\n    let interactionEvents = Publisher\u003cDemoInteractionEvents\u003e()\n    let data: DataObject\n    \n    // MARK: Life Cycle\n\n    init(data: DataObject) {\n        self.data = data\n        super.init()\n    }\n}\n\n```\n\n\n### ViewController\n\n```swift\nimport DeclarativeUI\n\nfinal class DemoViewController: DeclarativeViewController {\n\n    // MARK: Attributes\n\n    public lazy var viewController = ViewController(view: view)\n    private let viewModel: DemoViewModel\n    \n    private lazy var titlelLabel = Label(\n        text: viewModel.data.title,\n        style: .systemFont()\n    )\n    \n    private lazy var detailLabel = Label(\n        text: viewModel.data.detail\n        style: .boldSystemFont()\n    )\n\n    private lazy var valueLabel = Label(\n        text: viewModel.data.value\n        style: .boldSystemFont()\n    )\n\n    private let icon = Image()\n        .size(width: .medium, height: .medium)\n        .image(viewModel.data.icon)\n        \n    private lazy var view = StackView(.vertical) {\n        Spacer(.small)\n        titlelLabel\n        Spacer(.small)\n        StackView(.horizontal) {\n            icon\n            detailLabel\n        }.spacing(.extraSmall)\n        .alignment(.leading)\n        Spacer(.medium)\n        valueLabel       \n        Spacer(.flexible)\n    }.padding(.uniform(.small))\n    \n    // MARK: Life Cycle\n\n    public init(viewModel: DemoViewModel) {\n        self.viewModel = viewModel\n    }\n}\n\n```\n\n### Component\n\n```swift\nimport DeclarativeUI\n\npublic class Pager: DeclarativeComponent {\n    public lazy var view = stackView\n    \n    private lazy var stackView = StackView(.horizontal)\n        .distribution(.fillEqually)\n        .alignment(.center)\n        .spacing(.zero)\n        \n    private var buttons = [Page]()\n    private var selectedIndex = Publisher\u003cInt\u003e()\n    private let initialIndexSelected: Int\n    \n    public init(_ options: [String],\n                indexSelected: Int = 0) {\n        initialIndexSelected = indexSelected\n        options.enumerated().forEach { index, value in\n            let button = Page(value)\n                .onTap { [weak self] in\n                    self?.selectedIndex.publish(index)\n                }\n            if index == initialIndexSelected {\n                button.selectLayout()\n            } else {\n                button.normalLayout()\n            }\n            buttons.append(button)\n        }\n        stackView.update {\n            buttons as [UIViewConvertible]\n        }\n        \n        bindSelectedIndex()\n    }\n    \n    private func bindSelectedIndex() {\n        observe(selectedIndex) { [stackView, buttons] vc, indexSelected in\n            vc.buttons.enumerated().forEach { index, button in\n                if index == indexSelected {\n                    button.selectLayout()\n                } else {\n                    button.normalLayout()\n                }\n            }\n            stackView.update {\n                buttons as [UIViewConvertible]\n            }\n        }\n    }\n    \n    @discardableResult\n    public func didChangeValue(_ action: @escaping (Int?) -\u003e Void) -\u003e Self {\n        selectedIndex.subscribe().onNext { _, value in\n            action(value)\n        }.disposedBy(self)\n        return self\n    }\n}\n\nprivate class Page: DeclarativeComponent {\n    public lazy var view = ContainerView { stackView }\n    private let title = Label(style: .systemFont())\n    private let line = EmptyView()\n        .backgroundColor(.white)\n        .height(.extraSmall2)\n        .cornerRadius(.extraSmall3)\n    \n    private lazy var stackView = StackView(.vertical) {\n        title\n            .alignment(.center)\n        Spacer(.extraSmall)\n        line\n    }.distribution(.fill)\n\n    public init(_ title: String) {\n        self.title.text(title)\n    }\n    \n    public func selectLayout() {\n        title.style(.boldSystemFont())\n        line.backgroundColor(.black)\n    }\n    \n    public func normalLayout() {\n        title.style(.systemFont())\n        line.backgroundColor(.white)\n    }\n}\n\n```\n\n### Preview\n\n```swift\nimport SwiftUI\n@available(iOS 13.0.0, *)\nstruct Pager_Previews: PreviewProvider {\n    static var previews: some View {\n        ViewContainer(view: pager)\n            .previewDevice(\"iPhone 12\")\n    }\n\n    static var pager = StackView(.vertical) {\n        Spacer(.large)\n        Pager([\"Option 1\", \"Option 2\", \"Option 3\"])\n    }.padding(.horizontal(.medium))\n}\n```\n\n### Coordinator\n\n```swift\nimport DeclarativeUI\n\npublic final class DemoCoordinator: DeclarativeCoordinator {\n        \n    // MARK: Life Cycle\n    \n    public init() {\n        super.init()\n        start()\n    }\n    \n    public func start() {\n        navigateToDemo()\n    }\n    \n    private func navigateToDemo() {\n        let viewModel = DemoViewModel(data: DataObject())\n        \n        let viewController = DemoViewController(viewModel: viewModel)\n            .navigationBarOptions([.back, .close])\n            .navigationTitle(\"Title Navigation Bar\")\n\n        viewModel.interactionEvents.subscribe().onNext { event in\n            switch event {\n            case .rowSelect(let data):\n                self.navigateToDemoDetail(data: data)\n            case .iconOnTap:\n                self.navigateToIconTap()\n            }\n        }.disposedBy(self)\n\n        navigator.push(viewController)\n    }\n}\n```\n","funding_links":[],"categories":[],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fholistic-apps-ltda%2Fdeclarativeui","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fholistic-apps-ltda%2Fdeclarativeui","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fholistic-apps-ltda%2Fdeclarativeui/lists"}