{"id":30584995,"url":"https://github.com/dagronf/appkitui","last_synced_at":"2025-08-29T10:19:59.170Z","repository":{"id":312018344,"uuid":"1039871179","full_name":"dagronf/AppKitUI","owner":"dagronf","description":"AppKit DSL and conveniences. Simplify your AppKit code!","archived":false,"fork":false,"pushed_at":"2025-08-28T02:47:43.000Z","size":361,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":0,"default_branch":"main","last_synced_at":"2025-08-28T09:43:03.658Z","etag":null,"topics":[],"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/dagronf.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,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null}},"created_at":"2025-08-18T05:39:26.000Z","updated_at":"2025-08-28T02:47:45.000Z","dependencies_parsed_at":"2025-08-28T09:43:07.766Z","dependency_job_id":"f7170631-24fe-46aa-984f-2264e66edfab","html_url":"https://github.com/dagronf/AppKitUI","commit_stats":null,"previous_names":["dagronf/appkitui"],"tags_count":2,"template":false,"template_full_name":null,"purl":"pkg:github/dagronf/AppKitUI","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/dagronf%2FAppKitUI","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/dagronf%2FAppKitUI/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/dagronf%2FAppKitUI/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/dagronf%2FAppKitUI/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/dagronf","download_url":"https://codeload.github.com/dagronf/AppKitUI/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/dagronf%2FAppKitUI/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":272667786,"owners_count":24972984,"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","status":"online","status_checked_at":"2025-08-29T02:00:10.610Z","response_time":87,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"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":[],"created_at":"2025-08-29T10:19:58.486Z","updated_at":"2025-08-29T10:19:59.154Z","avatar_url":"https://github.com/dagronf.png","language":"Swift","funding_links":[],"categories":[],"sub_categories":[],"readme":"# AppKitUI\n\nAn AppKit UI toolkit help you create and manage `NSView` content easily \n\n1. Remove dependence on requiring XIBs when creating UI views\n2. Reduce boilerplate code when manually creating `NSView` UI content.\n3. Easily bind data between controls\n\nThere is a demo application in the 'Demo' folder that demonstrates many of the controls and features of this package. \n\nNote that this beta level code!  Feedback and bug reports are always appreciated.\n\n## Features\n\n* Chainable properties for most AppKit NS- UI controls.\n* Preview your AppKitUI user interface directly in Xcode's `#Preview` pane.\n* Remove the need to create XIBs for laying out a view.\n* Simplify building your UI, using a DSL similar to SwiftUI\n* Easily handle moving and updating data between controls (eg. the value of an `NSSlider`)\n* Compatible back to 10.13!\n\n## Chainable AppKit controls\n\nMost AppKit UI controls have added chaining functions for most of the control's properties.\n\nThis way you can create your control using a single statement.\n\nFor example :-\n\n```swift\nlet commitButton = NSButton(title: \"Commit\")\n   .bezelStyle(.push)\n   .image(commitImage)\n   .imagePosition(.imageLeading)\n```\n\n## Actions\n\nAppKitUI adds actions to many AppKit controls, which allows you to handle control callbacks without having\nto provide delegates or target/action pairs for the control.\n\n### Example 1: Add a press handler to an `NSButton`\n\n```\nNSButton(title: \"Present results\")\n   .onAction { [weak self] state in \n      // Do something when the button is pressed\n   }\n```\n\n### Example 2: handle changes in an `NSTextField`\n\n```swift\nNSTextField(string: \"Fish and chips\")\n   .width(200)\n   .onChange { newText in\n      // Do something with 'newText' when the text changes\n   }\n```\n\n### Example 3: Handle color changes in an `NSColorWell`\n\n```swift\nlet well = NSColorWell()\n   .supportsAlpha(true)\n   .color(.systemYellow)\n   .onColorChange { [weak self] newColor in\n      // Do something with 'newColor' when the color changes\n   }\n   .frame(width: 60, height: 60)\n```\n\n## Bindable Values\n\nMany UI controls take and manipulate values (eg. an NSSlider). AppKitUI can bind these values betwen different controls \nto drastically simplify your UI code.\n\n### Example 1: Basic NSSlider value\n\n```\nlet dockSize = Bind(0.4)   // The initial value for the slider\nlet dockSizeSlider = NSSlider(dockSize, range: 0 ... 1)\n                        .numberOfTickMarks(2)\n```\n\nBindings can also specify delays for things such as update throttling or debouncing.\n\n```swift\nlet delayedValue = Bind(20.0, delayType: .debounce(0.5))\nlet throttledValue = Bind(20.0, delayType: .throttle(0.5))\n```\n\n## UI Building\n\nAppKitUI supports building nested child views, similar to SwiftUI.  Note that this only constructs\na view heirarachy.\n\n```swift\nfunc makeMyExcitingView() -\u003e NSView {\n   VStack {\n      NSTextField(label: \"The first line\")\n      NSButton(title: \"Dance baby dance!\") { _ in\n         Swift.print(\"You clicked dance!\") \n      }\n      .tooltip(\"Do the important thing\")\n   }\n}\n```\n\nThere are a number of provided view structures :-\n\n|  Type              |  Description              |\n|--------------------|---------------------------|\n| `VStack`           | A vertical NSStackView    |\n| `HStack`           | A horizontal NSStackView  |\n| `NSGridView`       | A grid                    |\n| `Flow`             | A collection view that flows its child views horizontally, then moves to the next line when the row has run out of space |\n| `TabView`          | A NSTabView               |\n| `VSplitView`       | A vertical split view     |\n| `HSplitView`       | A horizontal split view   |\n| `ZStack`           | A z-order stack           |\n| `ScrollView`       | A scroll container        |\n| `LayoutContainer`  | A view container allowing arbitrary constraints between child views |\n\nThe fun part with this is that you can use Xcode previews to preview your NSView!\n\n```swift\n#if DEBUG\n\n@MainActor\nfunc makeDockSizeStack__(_ dockSize: Bind\u003cDouble\u003e) -\u003e NSView {\n   VStack(alignment: .leading, spacing: 4) {\n      NSTextField(label: \"Size:\")\n      NSSlider(dockSize, range: 0 ... 1)\n         .numberOfTickMarks(2)\n      HStack {\n         NSTextField(label: \"Small\")\n            .font(.caption2)\n            .gravityArea(.leading)\n         NSView.Spacer()\n         NSTextField(label: \"Large\")\n            .font(.caption2)\n            .gravityArea(.trailing)\n      }\n   }\n}\n\n@available(macOS 14, *)\n#Preview(\"Simple slider\") {\n\tlet dockSize = Bind(0.1)\n\tmakeDockSizeStack__(dockSize)\n\t\t.width(250)\n}\n\n#endif\n```\n\nXcode previews require macOS 14, so you'll need to `@available` the preview.  The good thing is that this works\neven if you are targeting macOS 10.13 (through the magic of backporting!).\n\nYou'll need to add the `DesignTime+PreviewBackport.swift` to your project for it to work.\n\nAlmost every source file for extending NS- controls has a preview (look in the `NS...+appkitui.swift` files in this package)\n\n## NSFont conveniences\n\nThis set of extensions adds a collection of convenience properties and methods to NSFont, making it easier to work with common font styles, symbolic traits (such as bold or italic), and semantic text roles similar to those found in iOS (UIFont.TextStyle).\nThese extensions are designed to simplify font creation, provide consistency across your app’s UI, and reduce boilerplate when dealing with different weights, sizes, and symbolic traits.\n\nThese extensions provide:\n\n* Semantic roles for text (body, headline, caption1, etc.).\n* Convenient trait modifiers like `.bold`, `.italic`, `.monospaced`.\n* Dynamic adjustments with `.size(_:)`, `.weight(_:)`, and `.traits(_)`.\n\n### Semantic Fonts\n\nSemantic system fonts let you specify fonts by role rather than point size.\n\n* `NSFont.body` – Body text (13pt).\n* `NSFont.callout` – Callouts (12pt).\n* `NSFont.caption1` – Standard captions (10pt).\n* `NSFont.caption2` – Alternate captions (≈10.5pt).\n* `NSFont.footnote` – Footnotes (≈10pt).\n* `NSFont.headline` – Headings (13pt, semibold).\n* `NSFont.subheadline` – Subheadings (11pt).\n* `NSFont.largeTitle` – Large titles (26pt).\n* `NSFont.title1` – First-level titles (22pt).\n* `NSFont.title2` – Second-level titles (17pt).\n* `NSFont.title3` – Third-level titles (15pt).\n\n### Monospaced Fonts\n\n* `NSFont.monospacedDigit` – System font with monospaced digits.\n* `NSFont.monospaced` – System monospaced font.\n\n- On macOS 10.15+, uses monospacedSystemFont.\n- On earlier macOS, falls back to a system font with .monoSpace traits.\n\n## License\n\n```\nMIT License\n\nCopyright (c) 2025 Darren Ford\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\nSOFTWARE.\n```\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fdagronf%2Fappkitui","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fdagronf%2Fappkitui","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fdagronf%2Fappkitui/lists"}