{"id":24541631,"url":"https://github.com/iSapozhnik/Menu","last_synced_at":"2025-10-03T17:31:14.038Z","repository":{"id":63912279,"uuid":"255714560","full_name":"iSapozhnik/Menu","owner":"iSapozhnik","description":"The most customizable menu for macOS apps.","archived":false,"fork":false,"pushed_at":"2021-11-19T22:04:48.000Z","size":1905,"stargazers_count":119,"open_issues_count":6,"forks_count":21,"subscribers_count":5,"default_branch":"master","last_synced_at":"2025-01-22T09:37:58.179Z","etag":null,"topics":["custom-menus","dropdown","mac","macos","menu","nsmenu","nspopupbutton","nswindow","nswindowcontroller","popup","swift"],"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/iSapozhnik.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":"2020-04-14T20:09:31.000Z","updated_at":"2025-01-05T00:23:19.000Z","dependencies_parsed_at":"2023-01-14T13:16:03.795Z","dependency_job_id":null,"html_url":"https://github.com/iSapozhnik/Menu","commit_stats":null,"previous_names":[],"tags_count":13,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/iSapozhnik%2FMenu","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/iSapozhnik%2FMenu/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/iSapozhnik%2FMenu/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/iSapozhnik%2FMenu/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/iSapozhnik","download_url":"https://codeload.github.com/iSapozhnik/Menu/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":235096184,"owners_count":18935182,"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":["custom-menus","dropdown","mac","macos","menu","nsmenu","nspopupbutton","nswindow","nswindowcontroller","popup","swift"],"created_at":"2025-01-22T18:18:15.243Z","updated_at":"2025-10-03T17:31:08.618Z","avatar_url":"https://github.com/iSapozhnik.png","language":"Swift","readme":"# Menu\n\n\u003cdiv align=\"center\"\u003e\n\n![Swift](https://img.shields.io/badge/%20in-swift%205.0-orange.svg)\n![macOS](https://img.shields.io/badge/macOS-10.12-green.svg)\n[![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)\n[![](https://img.shields.io/endpoint?url=https%3A%2F%2Fswiftpackageindex.com%2Fapi%2Fpackages%2FiSapozhnik%2FMenu%2Fbadge%3Ftype%3Dplatforms)](https://swiftpackageindex.com/iSapozhnik/Menu)\n\n\u003c/div\u003e\n\n\u003eFully customizable macOS drop-down menu. It includes **30** settings you can play with.\n\n![](screenshot2.png)\n\n## Requirements\n\n* Xcode 11+\n* macOS 10.12+\n* Swift 5.0 and higher\n\n## Installation\n\nSince this is a Swift Package, the installation process is pretty stright forward.\n\n### Manual way\nUpdate your `Package.swift` dependencies:\n\n```\ndependencies: [\n    .package(url: \"https://github.com/iSapozhnik/Menu\", from: \"1.10.1\")\n]\n```\n\n### Via Xcode:\n1. Go to `File -\u003e Swift Packages -\u003e Add Package Dependency`. \n2. Put GitHub URL `https://github.com/iSapozhnik/Menu` and click `Next`\n3. Select the latest version\n4. Click `Finish`\n\n## What can be customized? Everything!\n```swift\npublic protocol Configuration {\n    var titleBottomSpace: CGFloat                           { get }\n    var titleFont: NSFont?                                  { get }\n    var titleColor: NSColor                                 { get }\n    var backgroundColor: NSColor                            { get }\n    var cornerRadius: CGFloat                               { get }\n    var hasShadow: Bool                                     { get }\n    var appearsBelowSender: Bool                            { get }\n    var presentingOffset: CGFloat                           { get }\n    var animationDuration: TimeInterval                     { get }\n    var contentEdgeInsets: NSEdgeInsets                     { get }\n    var maximumContentHeight: CGFloat?                      { get }\n    var separatorColor: NSColor                             { get }\n    var separatorThickness: CGFloat                         { get }\n    var separatorHorizontalPadding: Padding.Horizontal      { get }\n    var separatorVerticlaPadding: Padding.Vertical          { get }\n    var rememberSelection: Bool                             { get }\n    var textAlignment: Alignment                            { get }\n    var iconAlignment: Alignment                            { get }\n    var menuItemFont: NSFont?                               { get }\n    var menuItemHeight: CGFloat                             { get }\n    var menuItemHoverBackgroundColor: NSColor               { get }\n    var menuItemTextColor: NSColor                          { get }\n    var menuItemHoverTextColor: NSColor                     { get }\n    var menuItemCheckmarkColor: NSColor                     { get }\n    var menuItemHoverCheckmarkColor: NSColor                { get }\n    var menuItemCheckmarkHeight: CGFloat                    { get }\n    var menuItemCheckmarkThikness: CGFloat                  { get }\n    var menuItemHorizontalSpacing: CGFloat                  { get }\n    var menuItemImageHeight: CGFloat?                       { get }\n    var menuItemImageTintColor: NSColor?                    { get }\n    var menuItemHoverImageTintColor: NSColor?               { get }\n    var menuItemHoverAnimationDuration: TimeInterval        { get }\n}\n```\n## How to use\n\n```swift\nimport Cocoa\nimport Menu\n\nclass ViewController: NSViewController {\n    private let myMenu = Menu(with: \"Select a search engine:\")\n\n    @IBOutlet var showMenuButton: NSButton!\n\n    override func viewDidLoad() {\n        super.viewDidLoad()\n\n        let bing = MenuItem(\"Bing search\", image: Icn.bing.image, action: { [weak self] in\n            self?.showMenuButton.title = \"Bing\"\n        })\n        let item = MenuItem(\"DuckDuckGo search\", image: Icn.duck.image, action: { [weak self] in\n            self?.showMenuButton.title = \"DuckDuckGo\"\n        })\n        let google = MenuItem(\"Google search\", image: Icn.google.image, action: { [weak self] in\n            self?.showMenuButton.title = \"Google\"\n        })\n        let longText = MenuItem(\"Some very-very-very long text with no icon\", action: { [weak self] in\n            self?.showMenuButton.title = \"Some very long text\"\n        })\n        let emojiItem = MenuItem(\"Emojis are here 😎🚀\", action: { [weak self] in\n            self?.showMenuButton.title = \"Emojis are here 😎🚀\"\n        })\n        let exit = MenuItem(\"Exit\", image: Icn.exit.image, action: {\n            NSApplication.shared.terminate(nil)\n        })\n        let separator = MenuItem.separator()\n        let menuItems = [\n            bing,\n            item,\n            google,\n            separator,\n            longText,\n            emojiItem,\n            separator,\n            exit\n        ]\n\n        myMenu.addItems(menuItems)\n    }\n\n    @IBAction func didClickButton(_ sender: NSButton) {\n        myMenu.show(from: sender)\n    }\n}\n```\n\n## Examples\n\nIn this section I've collected some examples of what can be i,plemented do using **Menu** control. On the left side some random example from Dribbble and on the right side my implementation.\n\n| Dribbble      | Menu          | Code          |\n| ------------- |:-------------:|:-------------:|\n| [link](https://dribbble.com/shots/4233782-Snooze-notifications-in-Twist) | |\n| ![](examples/twist.png)     | ![](examples/menu_twist.png) | |\n| [link](https://dribbble.com/shots/7055473-Dropdowns) | | |\n| ![](examples/example_0.png) | ![](examples/menu_0.png) | [code](examples/examples.md) |\n\n## Credits\n\nCreated and maintained by [**@iSapozhnik**](https://twitter.com/iSapozhnik).\n\n## License\n\nReleased under the MIT License. See `LICENSE` for details.\n\n\u003e**Copyright \u0026copy; 2020-present Sapozhnik Ivan.**\n\n\u003c!--\nhttps://dribbble.com/shots/4953294-Daily-UI-Challenge-04-Dropdown-Menu\nhttps://dribbble.com/shots/7055473-Dropdowns\n--\u003e\n\n\n","funding_links":[],"categories":["Swift"],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2FiSapozhnik%2FMenu","html_url":"https://awesome.ecosyste.ms/projects/github.com%2FiSapozhnik%2FMenu","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2FiSapozhnik%2FMenu/lists"}