├── .github ├── ISSUE_TEMPLATE.md └── ISSUE_TEMPLATE │ └── feature_request.md ├── .gitignore ├── .jazzy.yaml ├── .swiftlint.yml ├── .travis.yml ├── CODE_OF_CONDUCT.md ├── CONTRIBUTING.md ├── Demo └── Catalogue │ ├── Catalogue.xcodeproj │ ├── project.pbxproj │ └── project.xcworkspace │ │ └── contents.xcworkspacedata │ └── Catalogue │ ├── AppDelegate.swift │ ├── Assets.xcassets │ ├── AppIcon.appiconset │ │ └── Contents.json │ ├── Contents.json │ ├── grand-canyon.imageset │ │ ├── Contents.json │ │ └── grand-canyon.jpg │ └── template-icon.imageset │ │ ├── Contents.json │ │ └── template-icon.png │ ├── Base.lproj │ └── LaunchScreen.storyboard │ ├── BaseViewController.swift │ ├── ColorsDemoViewController.swift │ ├── DemoMenuViewController.swift │ ├── DesignSystem.swift │ ├── IconographyViewController.swift │ ├── Info.plist │ ├── LayoutDemoViewController.swift │ ├── Main.storyboard │ ├── MenuItem.swift │ ├── ScaleChartsViewController.swift │ ├── StyleDemoViewController.swift │ ├── Styles.swift │ ├── Theme+System.swift │ ├── ThemeDemoViewController.swift │ ├── ToolKitViewController.swift │ ├── Typography+AvenirNext.swift │ ├── Typography+Menlo.swift │ ├── Typography+OpenSans.swift │ ├── TypographyDemoViewController.swift │ ├── Utility.swift │ └── open-sans │ ├── Apache License.txt │ ├── OpenSans-Bold.ttf │ ├── OpenSans-BoldItalic.ttf │ ├── OpenSans-ExtraBold.ttf │ ├── OpenSans-ExtraBoldItalic.ttf │ ├── OpenSans-Italic.ttf │ ├── OpenSans-Light.ttf │ ├── OpenSans-LightItalic.ttf │ ├── OpenSans-Regular.ttf │ ├── OpenSans-Semibold.ttf │ └── OpenSans-SemiboldItalic.ttf ├── Documentation └── Usage.md ├── Doric.podspec ├── Doric.xcodeproj ├── project.pbxproj ├── project.xcworkspace │ ├── contents.xcworkspacedata │ └── xcshareddata │ │ └── IDEWorkspaceChecks.plist └── xcshareddata │ └── xcschemes │ └── Doric.xcscheme ├── Doric.xcworkspace ├── contents.xcworkspacedata └── xcshareddata │ └── IDEWorkspaceChecks.plist ├── LICENSE ├── PULL_REQUEST_TEMPLATE.md ├── README.md ├── Source ├── AnchorLayout.swift ├── Bundle+Extension.swift ├── CardView.swift ├── Colors.swift ├── Debug+Preview.swift ├── DesignDebuggerViewController.swift ├── Doric.h ├── Doric.swift ├── GradientColor.swift ├── GradientView.swift ├── GraphView.swift ├── Iconography.swift ├── Implemented.swift ├── Info.plist ├── Layout.swift ├── Notification.swift ├── Scale.swift ├── Style.swift ├── Theme.swift ├── Typography.swift ├── UIColor+Extension.swift ├── UIStackView+Border.swift ├── UIView+Guide.swift └── internal-icon-close.png ├── demo-screenshot.png ├── docs ├── Classes.html ├── Classes │ ├── CardView.html │ ├── Doric.html │ ├── DualThemeManager.html │ └── GradientView.html ├── Enums.html ├── Enums │ ├── ButtonHeight.html │ ├── IconSize.html │ ├── LayoutRelation.html │ ├── Shadow.html │ └── Space.html ├── Extensions.html ├── Extensions │ ├── Bundle.html │ ├── Notification.html │ ├── UIButton.html │ ├── UIColor.html │ ├── UIColor │ │ └── System.html │ ├── UIFont.html │ ├── UIImage.html │ ├── UIImageView.html │ ├── UIStackView.html │ ├── UIView.html │ └── UIView │ │ └── Guideline.html ├── Guides.html ├── Protocols.html ├── Protocols │ ├── Color.html │ ├── ColorPalette.html │ ├── DarkenColorSet.html │ ├── DualThemeSwitcher.html │ ├── DynamicTypeCustomTextStyleFont.html │ ├── DynamicTypeFont.html │ ├── DynamicTypography.html │ ├── ExtendedDarkenColorSet.html │ ├── ExtendedLightenColorSet.html │ ├── Font.html │ ├── FontConvertible.html │ ├── FullScale.html │ ├── GradientColor.html │ ├── LargerColorPalette.html │ ├── LayoutValueRepresentable.html │ ├── LightenColorSet.html │ ├── MainColorPalette.html │ ├── Scale.html │ ├── SemanticColorPalette.html │ ├── Style.html │ ├── SystemFont.html │ ├── Theme.html │ ├── ThemeListener.html │ ├── ThemeManager.html │ ├── ThemeSwitcher.html │ ├── TwoStateValueLevel.html │ ├── Typography.html │ ├── TypographyOptions.html │ └── ValueLevel.html ├── Structs.html ├── Structs │ ├── Border.html │ ├── CornerRadius.html │ ├── DefaultGrayScalePalette.html │ ├── DefaultSemanticColorPalette.html │ ├── FontDescription.html │ ├── Settings.html │ ├── SystemTypography.html │ ├── ThemeNotification.html │ └── Transparency.html ├── Typealiases.html ├── _config.yml ├── badge.svg ├── css │ ├── highlight.css │ └── jazzy.css ├── docsets │ ├── Doric.docset │ │ └── Contents │ │ │ ├── Info.plist │ │ │ └── Resources │ │ │ ├── Documents │ │ │ ├── Classes.html │ │ │ ├── Classes │ │ │ │ ├── CardView.html │ │ │ │ ├── Doric.html │ │ │ │ ├── DualThemeManager.html │ │ │ │ └── GradientView.html │ │ │ ├── Enums.html │ │ │ ├── Enums │ │ │ │ ├── ButtonHeight.html │ │ │ │ ├── IconSize.html │ │ │ │ ├── LayoutRelation.html │ │ │ │ ├── Shadow.html │ │ │ │ └── Space.html │ │ │ ├── Extensions.html │ │ │ ├── Extensions │ │ │ │ ├── Bundle.html │ │ │ │ ├── Notification.html │ │ │ │ ├── UIButton.html │ │ │ │ ├── UIColor.html │ │ │ │ ├── UIColor │ │ │ │ │ └── System.html │ │ │ │ ├── UIFont.html │ │ │ │ ├── UIImage.html │ │ │ │ ├── UIImageView.html │ │ │ │ ├── UIStackView.html │ │ │ │ ├── UIView.html │ │ │ │ └── UIView │ │ │ │ │ └── Guideline.html │ │ │ ├── Guides.html │ │ │ ├── Protocols.html │ │ │ ├── Protocols │ │ │ │ ├── Color.html │ │ │ │ ├── ColorPalette.html │ │ │ │ ├── DarkenColorSet.html │ │ │ │ ├── DualThemeSwitcher.html │ │ │ │ ├── DynamicTypeCustomTextStyleFont.html │ │ │ │ ├── DynamicTypeFont.html │ │ │ │ ├── DynamicTypography.html │ │ │ │ ├── ExtendedDarkenColorSet.html │ │ │ │ ├── ExtendedLightenColorSet.html │ │ │ │ ├── Font.html │ │ │ │ ├── FontConvertible.html │ │ │ │ ├── FullScale.html │ │ │ │ ├── GradientColor.html │ │ │ │ ├── LargerColorPalette.html │ │ │ │ ├── LayoutValueRepresentable.html │ │ │ │ ├── LightenColorSet.html │ │ │ │ ├── MainColorPalette.html │ │ │ │ ├── Scale.html │ │ │ │ ├── SemanticColorPalette.html │ │ │ │ ├── Style.html │ │ │ │ ├── SystemFont.html │ │ │ │ ├── Theme.html │ │ │ │ ├── ThemeListener.html │ │ │ │ ├── ThemeManager.html │ │ │ │ ├── ThemeSwitcher.html │ │ │ │ ├── TwoStateValueLevel.html │ │ │ │ ├── Typography.html │ │ │ │ ├── TypographyOptions.html │ │ │ │ └── ValueLevel.html │ │ │ ├── Structs.html │ │ │ ├── Structs │ │ │ │ ├── Border.html │ │ │ │ ├── CornerRadius.html │ │ │ │ ├── DefaultGrayScalePalette.html │ │ │ │ ├── DefaultSemanticColorPalette.html │ │ │ │ ├── FontDescription.html │ │ │ │ ├── Settings.html │ │ │ │ ├── SystemTypography.html │ │ │ │ ├── ThemeNotification.html │ │ │ │ └── Transparency.html │ │ │ ├── Typealiases.html │ │ │ ├── _config.yml │ │ │ ├── badge.svg │ │ │ ├── css │ │ │ │ ├── highlight.css │ │ │ │ └── jazzy.css │ │ │ ├── img │ │ │ │ ├── carat.png │ │ │ │ ├── dash.png │ │ │ │ └── gh.png │ │ │ ├── index.html │ │ │ ├── js │ │ │ │ ├── jazzy.js │ │ │ │ └── jquery.min.js │ │ │ ├── search.json │ │ │ └── usage.html │ │ │ └── docSet.dsidx │ ├── Doric.tgz │ └── Doric.xml ├── img │ ├── carat.png │ ├── dash.png │ └── gh.png ├── index.html ├── js │ ├── jazzy.js │ └── jquery.min.js ├── search.json └── usage.html ├── doric.png └── screens-preview.gif /.github/ISSUE_TEMPLATE.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: Bug report 3 | about: Create a report to help us improve 4 | title: '' 5 | labels: '' 6 | assignees: '' 7 | 8 | --- 9 | 10 | **Describe the bug** 11 | A clear and concise description of what the bug is. 12 | 13 | **To Reproduce** 14 | Steps to reproduce the behavior or demo app: 15 | 16 | **Expected behavior** 17 | A clear and concise description of what you expected to happen. 18 | 19 | **Screenshots** 20 | If applicable, add screenshots to help explain your problem. 21 | 22 | 23 | **Smartphone (please complete the following information):** 24 | - Device: [e.g. iPhone6] 25 | - OS Version: [e.g. iOS11.1] 26 | 27 | **Additional context** 28 | Add any other context about the problem here. 29 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/feature_request.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: Feature request 3 | about: Suggest an idea for this project 4 | title: '' 5 | labels: '' 6 | assignees: '' 7 | 8 | --- 9 | 10 | **Is your feature request related to a problem? Please describe.** 11 | A clear and concise description of what the problem is. Ex. I'm always frustrated when [...] 12 | 13 | **Describe the solution you'd like** 14 | A clear and concise description of what you want to happen. 15 | 16 | **Describe alternatives you've considered** 17 | A clear and concise description of any alternative solutions or features you've considered. 18 | 19 | **Additional context** 20 | Add any other context or screenshots about the feature request here. 21 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Xcode 2 | # 3 | # gitignore contributors: remember to update Global/Xcode.gitignore, Objective-C.gitignore & Swift.gitignore 4 | 5 | ## Build generated 6 | build/ 7 | DerivedData/ 8 | 9 | ## Various settings 10 | *.pbxuser 11 | !default.pbxuser 12 | *.mode1v3 13 | !default.mode1v3 14 | *.mode2v3 15 | !default.mode2v3 16 | *.perspectivev3 17 | !default.perspectivev3 18 | xcuserdata/ 19 | 20 | ## Other 21 | *.moved-aside 22 | *.xccheckout 23 | *.xcscmblueprint 24 | 25 | ## Obj-C/Swift specific 26 | *.hmap 27 | *.ipa 28 | *.dSYM.zip 29 | *.dSYM 30 | 31 | ## Playgrounds 32 | timeline.xctimeline 33 | playground.xcworkspace 34 | 35 | # Swift Package Manager 36 | # 37 | # Add this line if you want to avoid checking in source code from Swift Package Manager dependencies. 38 | # Packages/ 39 | # Package.pins 40 | # Package.resolved 41 | .build/ 42 | 43 | # CocoaPods 44 | # 45 | # We recommend against adding the Pods directory to your .gitignore. However 46 | # you should judge for yourself, the pros and cons are mentioned at: 47 | # https://guides.cocoapods.org/using/using-cocoapods.html#should-i-check-the-pods-directory-into-source-control 48 | # 49 | # Pods/ 50 | 51 | # Carthage 52 | # 53 | # Add this line if you want to avoid checking in source code from Carthage dependencies. 54 | # Carthage/Checkouts 55 | 56 | Carthage/Build 57 | 58 | # fastlane 59 | # 60 | # It is recommended to not store the screenshots in the git repo. Instead, use fastlane to re-generate the 61 | # screenshots whenever they are needed. 62 | # For more information about the recommended setup visit: 63 | # https://docs.fastlane.tools/best-practices/source-control/#source-control 64 | 65 | fastlane/report.xml 66 | fastlane/Preview.html 67 | fastlane/screenshots/**/*.png 68 | fastlane/test_output 69 | -------------------------------------------------------------------------------- /.jazzy.yaml: -------------------------------------------------------------------------------- 1 | author: Jay K 2 | author_url: https://github.com/jayeshk/Doric 3 | github_url: https://github.com/jayeshk/Doric 4 | root_url: https://github.com/jayeshk/Doric/ 5 | module: Doric 6 | output: docs 7 | theme: apple 8 | xcodebuild_arguments: [-project, 'Doric.xcodeproj', -scheme, 'Doric'] 9 | theme: apple 10 | exclude: 11 | - './Source/Debug+Preview.swift' 12 | documentation: Documentation/*.md 13 | -------------------------------------------------------------------------------- /.swiftlint.yml: -------------------------------------------------------------------------------- 1 | ##included: 2 | ## - Source 3 | disabled_rules: # rule identifiers to exclude from running 4 | - colon 5 | - line_length 6 | 7 | excluded: # paths to ignore during linting. Takes precedence over `included`. 8 | - Source/Debug+Preview.swift 9 | -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | os: osx 2 | osx_image: xcode10.2 3 | branches: 4 | only: 5 | - master 6 | script: 7 | - xcodebuild -version 8 | - xcodebuild -showsdks 9 | 10 | # Build Framework 11 | - xcodebuild -project Doric.xcodeproj -scheme "Doric" -destination "OS=12.0,name=iPhone XS" -configuration Release 12 | -------------------------------------------------------------------------------- /CODE_OF_CONDUCT.md: -------------------------------------------------------------------------------- 1 | # Contributor Covenant Code of Conduct 2 | 3 | ## Our Pledge 4 | 5 | In the interest of fostering an open and welcoming environment, we as 6 | contributors and maintainers pledge to making participation in our project and 7 | our community a harassment-free experience for everyone, regardless of age, body 8 | size, disability, ethnicity, sex characteristics, gender identity and expression, 9 | level of experience, education, socio-economic status, nationality, personal 10 | appearance, race, religion, or sexual identity and orientation. 11 | 12 | ## Our Standards 13 | 14 | Examples of behavior that contributes to creating a positive environment 15 | include: 16 | 17 | * Using welcoming and inclusive language 18 | * Being respectful of differing viewpoints and experiences 19 | * Gracefully accepting constructive criticism 20 | * Focusing on what is best for the community 21 | * Showing empathy towards other community members 22 | 23 | Examples of unacceptable behavior by participants include: 24 | 25 | * The use of sexualized language or imagery and unwelcome sexual attention or 26 | advances 27 | * Trolling, insulting/derogatory comments, and personal or political attacks 28 | * Public or private harassment 29 | * Publishing others' private information, such as a physical or electronic 30 | address, without explicit permission 31 | * Other conduct which could reasonably be considered inappropriate in a 32 | professional setting 33 | 34 | ## Our Responsibilities 35 | 36 | Project maintainers are responsible for clarifying the standards of acceptable 37 | behavior and are expected to take appropriate and fair corrective action in 38 | response to any instances of unacceptable behavior. 39 | 40 | Project maintainers have the right and responsibility to remove, edit, or 41 | reject comments, commits, code, wiki edits, issues, and other contributions 42 | that are not aligned to this Code of Conduct, or to ban temporarily or 43 | permanently any contributor for other behaviors that they deem inappropriate, 44 | threatening, offensive, or harmful. 45 | 46 | ## Scope 47 | 48 | This Code of Conduct applies both within project spaces and in public spaces 49 | when an individual is representing the project or its community. Examples of 50 | representing a project or community include using an official project e-mail 51 | address, posting via an official social media account, or acting as an appointed 52 | representative at an online or offline event. Representation of a project may be 53 | further defined and clarified by project maintainers. 54 | 55 | ## Enforcement 56 | 57 | Instances of abusive, harassing, or otherwise unacceptable behavior may be 58 | reported by contacting the project team at doricdesignsystem@gmail.com. All 59 | complaints will be reviewed and investigated and will result in a response that 60 | is deemed necessary and appropriate to the circumstances. The project team is 61 | obligated to maintain confidentiality with regard to the reporter of an incident. 62 | Further details of specific enforcement policies may be posted separately. 63 | 64 | Project maintainers who do not follow or enforce the Code of Conduct in good 65 | faith may face temporary or permanent repercussions as determined by other 66 | members of the project's leadership. 67 | 68 | ## Attribution 69 | 70 | This Code of Conduct is adapted from the [Contributor Covenant][homepage], version 1.4, 71 | available at https://www.contributor-covenant.org/version/1/4/code-of-conduct.html 72 | 73 | [homepage]: https://www.contributor-covenant.org 74 | 75 | For answers to common questions about this code of conduct, see 76 | https://www.contributor-covenant.org/faq 77 | -------------------------------------------------------------------------------- /CONTRIBUTING.md: -------------------------------------------------------------------------------- 1 | Please raise PR with mentioned changes and explaing feature or bug. 2 | -------------------------------------------------------------------------------- /Demo/Catalogue/Catalogue.xcodeproj/project.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /Demo/Catalogue/Catalogue/AppDelegate.swift: -------------------------------------------------------------------------------- 1 | // Doric 2 | // 3 | // Copyright (c) 2019 Jay K. 4 | // 5 | // Permission is hereby granted, free of charge, to any person obtaining a copy 6 | // of this software and associated documentation files (the "Software"), to deal 7 | // in the Software without restriction, including without limitation the rights 8 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | // copies of the Software, and to permit persons to whom the Software is 10 | // furnished to do so, subject to the following conditions: 11 | // 12 | // The above copyright notice and this permission notice shall be included in 13 | // all copies or substantial portions of the Software. 14 | // 15 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 21 | // THE SOFTWARE. 22 | 23 | import Doric 24 | import UIKit 25 | 26 | @UIApplicationMain 27 | class AppDelegate: UIResponder, UIApplicationDelegate { 28 | var window: UIWindow? 29 | var themeManager: DualThemeManager! 30 | 31 | func application(_: UIApplication, didFinishLaunchingWithOptions _: [UIApplication.LaunchOptionsKey: Any]? = nil) -> Bool { 32 | prepareToolkit() 33 | prepareThemeManager() 34 | registerForThemeNotification() 35 | 36 | if let nController = self.window?.rootViewController as? UINavigationController { 37 | let navigationBar = nController.navigationBar 38 | navigationBar.applyStyle(navigationStyle: AppNavigationStyle.regular) 39 | } 40 | 41 | return true 42 | } 43 | 44 | func prepareToolkit() { 45 | Doric.shared.settings = Settings(spacing: Space.p1) 46 | Doric.shared.isHidden = true 47 | } 48 | 49 | func prepareThemeManager() { 50 | themeManager = DualThemeManager(mainTheme: DemoPrimaryTheme(), alternateTheme: DemoSecondaryTheme()) 51 | } 52 | 53 | func registerForThemeNotification() { 54 | NotificationCenter.default.addObserver(self, selector: #selector(onThemeChanged(_:)), name: ThemeNotification.didChange, object: nil) 55 | } 56 | 57 | @objc func onThemeChanged(_ notification: Notification) { 58 | guard let theme = notification.theme else { 59 | return 60 | } 61 | DemoDesignSystem.colorPalette = theme.colorPalette 62 | } 63 | } 64 | -------------------------------------------------------------------------------- /Demo/Catalogue/Catalogue/Assets.xcassets/AppIcon.appiconset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "iphone", 5 | "size" : "20x20", 6 | "scale" : "2x" 7 | }, 8 | { 9 | "idiom" : "iphone", 10 | "size" : "20x20", 11 | "scale" : "3x" 12 | }, 13 | { 14 | "idiom" : "iphone", 15 | "size" : "29x29", 16 | "scale" : "2x" 17 | }, 18 | { 19 | "idiom" : "iphone", 20 | "size" : "29x29", 21 | "scale" : "3x" 22 | }, 23 | { 24 | "idiom" : "iphone", 25 | "size" : "40x40", 26 | "scale" : "2x" 27 | }, 28 | { 29 | "idiom" : "iphone", 30 | "size" : "40x40", 31 | "scale" : "3x" 32 | }, 33 | { 34 | "idiom" : "iphone", 35 | "size" : "60x60", 36 | "scale" : "2x" 37 | }, 38 | { 39 | "idiom" : "iphone", 40 | "size" : "60x60", 41 | "scale" : "3x" 42 | }, 43 | { 44 | "idiom" : "ipad", 45 | "size" : "20x20", 46 | "scale" : "1x" 47 | }, 48 | { 49 | "idiom" : "ipad", 50 | "size" : "20x20", 51 | "scale" : "2x" 52 | }, 53 | { 54 | "idiom" : "ipad", 55 | "size" : "29x29", 56 | "scale" : "1x" 57 | }, 58 | { 59 | "idiom" : "ipad", 60 | "size" : "29x29", 61 | "scale" : "2x" 62 | }, 63 | { 64 | "idiom" : "ipad", 65 | "size" : "40x40", 66 | "scale" : "1x" 67 | }, 68 | { 69 | "idiom" : "ipad", 70 | "size" : "40x40", 71 | "scale" : "2x" 72 | }, 73 | { 74 | "idiom" : "ipad", 75 | "size" : "76x76", 76 | "scale" : "1x" 77 | }, 78 | { 79 | "idiom" : "ipad", 80 | "size" : "76x76", 81 | "scale" : "2x" 82 | }, 83 | { 84 | "idiom" : "ipad", 85 | "size" : "83.5x83.5", 86 | "scale" : "2x" 87 | }, 88 | { 89 | "idiom" : "ios-marketing", 90 | "size" : "1024x1024", 91 | "scale" : "1x" 92 | } 93 | ], 94 | "info" : { 95 | "version" : 1, 96 | "author" : "xcode" 97 | } 98 | } -------------------------------------------------------------------------------- /Demo/Catalogue/Catalogue/Assets.xcassets/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "info" : { 3 | "version" : 1, 4 | "author" : "xcode" 5 | } 6 | } -------------------------------------------------------------------------------- /Demo/Catalogue/Catalogue/Assets.xcassets/grand-canyon.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "scale" : "1x" 6 | }, 7 | { 8 | "idiom" : "universal", 9 | "filename" : "grand-canyon.jpg", 10 | "scale" : "2x" 11 | }, 12 | { 13 | "idiom" : "universal", 14 | "scale" : "3x" 15 | } 16 | ], 17 | "info" : { 18 | "version" : 1, 19 | "author" : "xcode" 20 | } 21 | } -------------------------------------------------------------------------------- /Demo/Catalogue/Catalogue/Assets.xcassets/grand-canyon.imageset/grand-canyon.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jayeshk/Doric/2629fb2d1328fdbf7d76a8583e3931caa8238168/Demo/Catalogue/Catalogue/Assets.xcassets/grand-canyon.imageset/grand-canyon.jpg -------------------------------------------------------------------------------- /Demo/Catalogue/Catalogue/Assets.xcassets/template-icon.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "scale" : "1x" 6 | }, 7 | { 8 | "idiom" : "universal", 9 | "filename" : "template-icon.png", 10 | "scale" : "2x" 11 | }, 12 | { 13 | "idiom" : "universal", 14 | "scale" : "3x" 15 | } 16 | ], 17 | "info" : { 18 | "version" : 1, 19 | "author" : "xcode" 20 | } 21 | } -------------------------------------------------------------------------------- /Demo/Catalogue/Catalogue/Assets.xcassets/template-icon.imageset/template-icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jayeshk/Doric/2629fb2d1328fdbf7d76a8583e3931caa8238168/Demo/Catalogue/Catalogue/Assets.xcassets/template-icon.imageset/template-icon.png -------------------------------------------------------------------------------- /Demo/Catalogue/Catalogue/Base.lproj/LaunchScreen.storyboard: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | -------------------------------------------------------------------------------- /Demo/Catalogue/Catalogue/BaseViewController.swift: -------------------------------------------------------------------------------- 1 | // Doric 2 | // 3 | // Copyright (c) 2019 Jay K. 4 | // 5 | // Permission is hereby granted, free of charge, to any person obtaining a copy 6 | // of this software and associated documentation files (the "Software"), to deal 7 | // in the Software without restriction, including without limitation the rights 8 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | // copies of the Software, and to permit persons to whom the Software is 10 | // furnished to do so, subject to the following conditions: 11 | // 12 | // The above copyright notice and this permission notice shall be included in 13 | // all copies or substantial portions of the Software. 14 | // 15 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 21 | // THE SOFTWARE. 22 | 23 | import Doric 24 | import UIKit 25 | 26 | class BaseViewController: UIViewController { 27 | override var preferredStatusBarStyle: UIStatusBarStyle { return UIStatusBarStyle.lightContent } 28 | 29 | func embedInScrollView() -> UIScrollView { 30 | let scrollView = UIScrollView() 31 | view.addSubview(scrollView) 32 | scrollView.bounces = true 33 | scrollView.anchorEdges(view) 34 | scrollView.backgroundColor = UIColor.clear 35 | return scrollView 36 | } 37 | 38 | override func viewDidLoad() { 39 | super.viewDidLoad() 40 | registerForThemeNotification() 41 | prepareForStyle() 42 | } 43 | 44 | func prepareForStyle() { 45 | view.applyStyle(viewStyle: AppViewStyle.main) 46 | } 47 | 48 | func presentOptions(_ alert: UIAlertController, barButtonItem: UIBarButtonItem? = nil) { 49 | alert.view.tintColor = DemoDesignSystem.colorPalette.black 50 | if traitCollection.userInterfaceIdiom == .pad { 51 | alert.popoverPresentationController?.barButtonItem = barButtonItem 52 | } 53 | present(alert, animated: true, completion: nil) 54 | } 55 | 56 | func registerForThemeNotification() { 57 | NotificationCenter.default.addObserver(self, selector: #selector(onThemeChanged(_:)), name: ThemeNotification.didChange, object: nil) 58 | } 59 | @objc func onThemeChanged(_ notification: Notification) { 60 | guard let theme = notification.theme else { 61 | return 62 | } 63 | updateUIOnThemeChange(theme) 64 | } 65 | 66 | func updateUIOnThemeChange(_: Theme) { 67 | prepareForStyle() 68 | } 69 | } 70 | -------------------------------------------------------------------------------- /Demo/Catalogue/Catalogue/ColorsDemoViewController.swift: -------------------------------------------------------------------------------- 1 | // Doric 2 | // 3 | // Copyright (c) 2019 Jay K. 4 | // 5 | // Permission is hereby granted, free of charge, to any person obtaining a copy 6 | // of this software and associated documentation files (the "Software"), to deal 7 | // in the Software without restriction, including without limitation the rights 8 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | // copies of the Software, and to permit persons to whom the Software is 10 | // furnished to do so, subject to the following conditions: 11 | // 12 | // The above copyright notice and this permission notice shall be included in 13 | // all copies or substantial portions of the Software. 14 | // 15 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 21 | // THE SOFTWARE. 22 | 23 | import Doric 24 | import UIKit 25 | 26 | class ColorPreviewCell: UITableViewCell { 27 | @IBOutlet var nameLabel: UILabel! 28 | @IBOutlet var valueLabel: UILabel! 29 | @IBOutlet var preview: UIView! 30 | } 31 | 32 | class ColorsDemoViewController: BaseViewController { 33 | @IBOutlet var tableView: UITableView! 34 | 35 | var colors: [NamedColor] = [] 36 | 37 | override func viewDidLoad() { 38 | super.viewDidLoad() 39 | 40 | title = "Primary Colors" 41 | 42 | colors = DemoDesignSystem.colorPalette.primary.namedColors 43 | 44 | let optionsBarItem = UIBarButtonItem(title: "Options", style: .plain, target: self, action: #selector(showOptions)) 45 | navigationItem.rightBarButtonItem = optionsBarItem 46 | 47 | prepareStyle() 48 | } 49 | 50 | override func updateUIOnThemeChange(_: Theme) { 51 | prepareStyle() 52 | } 53 | 54 | func prepareStyle() { 55 | view.applyStyle(viewStyle: AppViewStyle.main) 56 | AppTableViewStyle.regular.performStyle(on: tableView) 57 | AppBarButtonItemStyle.regular.performStyle(on: navigationItem.rightBarButtonItem!) 58 | } 59 | 60 | @objc func showOptions() { 61 | let alert = UIAlertController(title: "Show colors", message: nil, preferredStyle: .actionSheet) 62 | 63 | let action1 = UIAlertAction(title: "Primary Color", style: .default) { _ in 64 | self.title = "Primary Colors" 65 | self.colors = DemoDesignSystem.colorPalette.primary.namedColors 66 | self.tableView.reloadData() 67 | } 68 | 69 | let action2 = UIAlertAction(title: "Secondary Color", style: .default) { _ in 70 | self.title = "Secondary Colors" 71 | self.colors = DemoDesignSystem.colorPalette.secondary.namedColors 72 | self.tableView.reloadData() 73 | } 74 | 75 | let action3 = UIAlertAction(title: "Supplimentory Color", style: .default) { _ in 76 | self.title = "Supplimentory Colors" 77 | self.colors = DemoDesignSystem.colorPalette.supplimentory.namedColors 78 | self.tableView.reloadData() 79 | } 80 | 81 | let action4 = UIAlertAction(title: "Grayscale Color", style: .default) { _ in 82 | self.title = "Grayscale Colors" 83 | self.colors = DemoDesignSystem.colorPalette.grayscale.namedColors 84 | self.tableView.reloadData() 85 | } 86 | 87 | let action5 = UIAlertAction(title: "Semantic Color", style: .default) { _ in 88 | self.title = "Semantic Colors" 89 | self.colors = DemoDesignSystem.colorPalette.semantic.previewItems() 90 | self.tableView.reloadData() 91 | } 92 | 93 | let cancel = UIAlertAction(title: "Cancel", style: .cancel) { _ in 94 | } 95 | 96 | alert.addAction(action1) 97 | alert.addAction(action2) 98 | alert.addAction(action3) 99 | alert.addAction(action4) 100 | alert.addAction(action5) 101 | 102 | alert.addAction(cancel) 103 | 104 | presentOptions(alert, barButtonItem: navigationItem.rightBarButtonItem) 105 | } 106 | } 107 | 108 | extension ColorsDemoViewController: UITableViewDelegate, UITableViewDataSource { 109 | func tableView(_: UITableView, numberOfRowsInSection _: Int) -> Int { 110 | return colors.count 111 | } 112 | 113 | func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell { 114 | let color = colors[indexPath.row] 115 | // swiftlint:disable force_cast 116 | let cell = tableView.dequeueReusableCell(withIdentifier: "ColorPreviewCell", for: indexPath) as! ColorPreviewCell 117 | // swiftlint:enable force_cast 118 | 119 | cell.nameLabel.text = color.0 120 | cell.valueLabel.text = color.1.hexString.uppercased() 121 | cell.preview.backgroundColor = color.1 122 | cell.nameLabel.applyStyle(labelStyle: AppLabelStyle.title) 123 | cell.valueLabel.applyStyle(labelStyle: AppLabelStyle.subtitle) 124 | return cell 125 | } 126 | } 127 | -------------------------------------------------------------------------------- /Demo/Catalogue/Catalogue/DemoMenuViewController.swift: -------------------------------------------------------------------------------- 1 | // Doric 2 | // 3 | // Copyright (c) 2019 Jay K. 4 | // 5 | // Permission is hereby granted, free of charge, to any person obtaining a copy 6 | // of this software and associated documentation files (the "Software"), to deal 7 | // in the Software without restriction, including without limitation the rights 8 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | // copies of the Software, and to permit persons to whom the Software is 10 | // furnished to do so, subject to the following conditions: 11 | // 12 | // The above copyright notice and this permission notice shall be included in 13 | // all copies or substantial portions of the Software. 14 | // 15 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 21 | // THE SOFTWARE. 22 | 23 | import Doric 24 | import UIKit 25 | 26 | class DemoMenuViewController: BaseViewController { 27 | let menuItems = MenuItem.allCases 28 | 29 | @IBOutlet var tableView: UITableView! 30 | 31 | override func viewDidLoad() { 32 | super.viewDidLoad() 33 | 34 | prepareStyle() 35 | } 36 | 37 | override func updateUIOnThemeChange(_: Theme) { 38 | prepareStyle() 39 | tableView.reloadData() 40 | } 41 | 42 | func prepareStyle() { 43 | view.applyStyle(viewStyle: AppViewStyle.main) 44 | AppTableViewStyle.regular.performStyle(on: tableView) 45 | navigationController!.navigationBar.applyStyle(navigationStyle: AppNavigationStyle.regular) 46 | } 47 | } 48 | 49 | extension DemoMenuViewController: UITableViewDataSource, UITableViewDelegate { 50 | func tableView(_: UITableView, numberOfRowsInSection _: Int) -> Int { 51 | return menuItems.count 52 | } 53 | 54 | func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell { 55 | let cell = tableView.dequeueReusableCell(withIdentifier: "Cell", for: indexPath) 56 | cell.textLabel?.text = menuItems[indexPath.row].display 57 | cell.textLabel?.applyStyle(labelStyle: AppLabelStyle.title) 58 | 59 | AppTableViewCellStyle.regular.performStyle(on: cell) 60 | return cell 61 | } 62 | 63 | override func prepare(for segue: UIStoryboardSegue, sender: Any?) { 64 | if let indexPath = sender as? IndexPath, let viewController = segue.destination as? ScaleChartsViewController { 65 | let menuItem = menuItems[indexPath.row] 66 | 67 | if menuItem == .borders { 68 | viewController.demoType = .border 69 | } else if menuItem == .cornerRadius { 70 | viewController.demoType = .cornerRadius 71 | } else if menuItem == .scaleChart { 72 | viewController.demoType = .scaleChart 73 | } 74 | } 75 | } 76 | 77 | func tableView(_: UITableView, didSelectRowAt indexPath: IndexPath) { 78 | let menuItem = menuItems[indexPath.row] 79 | performSegue(withIdentifier: menuItem.segueIdentifier, sender: indexPath) 80 | } 81 | } 82 | -------------------------------------------------------------------------------- /Demo/Catalogue/Catalogue/DesignSystem.swift: -------------------------------------------------------------------------------- 1 | // Doric 2 | // 3 | // Copyright (c) 2019 Jay K. 4 | // 5 | // Permission is hereby granted, free of charge, to any person obtaining a copy 6 | // of this software and associated documentation files (the "Software"), to deal 7 | // in the Software without restriction, including without limitation the rights 8 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | // copies of the Software, and to permit persons to whom the Software is 10 | // furnished to do so, subject to the following conditions: 11 | // 12 | // The above copyright notice and this permission notice shall be included in 13 | // all copies or substantial portions of the Software. 14 | // 15 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 21 | // THE SOFTWARE. 22 | 23 | import Doric 24 | import UIKit 25 | 26 | // MARK: - Colors 27 | 28 | // Example Color System Implemented by client 29 | 30 | public struct DoricDemoPrimaryColor: ColorPalette { 31 | public static let base = UIColor.System.purple 32 | } 33 | 34 | public struct DoricDemoSecondaryColor: ColorPalette { 35 | public static let base = UIColor.System.pink 36 | } 37 | 38 | public struct DoricDemoSupplimantoryColor: ColorPalette { 39 | public static let base = UIColor("#013e62") 40 | } 41 | 42 | struct DemoColorPalette: MainColorPalette { 43 | static let primary: ColorPalette.Type = DoricDemoPrimaryColor.self 44 | static let secondary: ColorPalette.Type = DoricDemoSecondaryColor.self 45 | static let supplimentory: ColorPalette.Type = DoricDemoSupplimantoryColor.self 46 | static var semantic: SemanticColorPalette.Type = DefaultSemanticColorPalette.self 47 | static let grayscale: LargerColorPalette.Type = DefaultGrayScalePalette.self 48 | } 49 | 50 | // MARK: - Design System 51 | 52 | class DemoDesignSystem { 53 | private init() {} 54 | 55 | static var colorPalette: MainColorPalette.Type = DemoColorPalette.self 56 | static let border: Scale.Type = Border.self 57 | static let cornerRadius: CornerRadiusSize = CornerRadius.self 58 | static let transparency: TransparencyLevel.Type = Transparency.self 59 | // static let typography: SystemTypography.Type = SystemTypography.self 60 | // static let typography: OpenSansTypography.Type = OpenSansTypography.self 61 | static let typography: DoricDemoTypography.Type = DoricDemoTypography.self 62 | } 63 | 64 | // MARK: - Size Charts 65 | 66 | struct DoricDemoBorderSize: Scale { 67 | static var small: CGFloat = 0.5 68 | static var medium: CGFloat = 1.0 69 | static var large: CGFloat = 2.0 70 | } 71 | -------------------------------------------------------------------------------- /Demo/Catalogue/Catalogue/IconographyViewController.swift: -------------------------------------------------------------------------------- 1 | // Doric 2 | // 3 | // Copyright (c) 2019 Jay K. 4 | // 5 | // Permission is hereby granted, free of charge, to any person obtaining a copy 6 | // of this software and associated documentation files (the "Software"), to deal 7 | // in the Software without restriction, including without limitation the rights 8 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | // copies of the Software, and to permit persons to whom the Software is 10 | // furnished to do so, subject to the following conditions: 11 | // 12 | // The above copyright notice and this permission notice shall be included in 13 | // all copies or substantial portions of the Software. 14 | // 15 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 21 | // THE SOFTWARE. 22 | 23 | import Doric 24 | import UIKit 25 | 26 | class IconographyViewController: BaseViewController { 27 | let demoImageName = "template-icon" 28 | 29 | var colorStackView: UIStackView! 30 | var sizeStackView: UIStackView! 31 | 32 | override func viewDidLoad() { 33 | super.viewDidLoad() 34 | 35 | title = "Iconography" 36 | 37 | createColorStack() 38 | createSizeStackView() 39 | 40 | prepareStyle() 41 | } 42 | 43 | override func updateUIOnThemeChange(_: Theme) { 44 | prepareStyle() 45 | } 46 | 47 | func prepareStyle() { 48 | view.applyStyle(viewStyle: AppViewStyle.main) 49 | } 50 | 51 | @objc func onBack() { 52 | navigationController?.popViewController(animated: true) 53 | } 54 | 55 | func createColorStack() { 56 | let primaryColor = DemoDesignSystem.colorPalette.primary.base 57 | let secondaryColor = DemoDesignSystem.colorPalette.secondary.base 58 | let supplimentory = DemoDesignSystem.colorPalette.supplimentory.base 59 | 60 | let image1 = UIImage.template(named: demoImageName, tintColor: primaryColor) 61 | let image2 = UIImage.template(named: demoImageName, tintColor: secondaryColor) 62 | let image3 = UIImage.template(named: demoImageName, tintColor: supplimentory) 63 | let image4 = UIImage.template(named: demoImageName) 64 | 65 | let stack1 = createStackView("Primary Color", image: image1) 66 | let stack2 = createStackView("Secondary Color", image: image2) 67 | let stack3 = createStackView("Supplimentory Color", image: image3) 68 | let stack4 = createStackView("Default Color", image: image4) 69 | 70 | colorStackView = UIStackView(arrangedSubviews: [stack1, stack2, stack3, stack4]) 71 | colorStackView.axis = .vertical 72 | colorStackView.spacing = Space.p1.rawValue 73 | view.addSubview(colorStackView) 74 | 75 | colorStackView.anchorLeft(view, constant: .equalTo(Space.p2)) 76 | colorStackView.anchorTop(view, constant: .equalTo(Space.p2)) 77 | } 78 | 79 | func createSizeStackView() { 80 | let headingLabel = UILabel() 81 | headingLabel.text = "*Icon sizes" 82 | 83 | headingLabel.applyStyle(labelStyle: AppLabelStyle.header) 84 | 85 | view.addSubview(headingLabel) 86 | 87 | sizeStackView = UIStackView(arrangedSubviews: []) 88 | sizeStackView.axis = .vertical 89 | sizeStackView.spacing = Space.p1.rawValue 90 | 91 | view.addSubview(sizeStackView) 92 | 93 | headingLabel.anchorWidth(sizeStackView) 94 | headingLabel.anchorLeading(sizeStackView) 95 | headingLabel.anchorTop(colorStackView.bottomAnchor, constant: .equalTo(Space.p2)) 96 | 97 | sizeStackView.anchorLeft(view, constant: .equalTo(Space.p2)) 98 | sizeStackView.anchorTop(headingLabel.bottomAnchor, constant: .equalTo(Space.p2)) 99 | 100 | sizeStackView.alignment = .fill 101 | sizeStackView.distribution = .fill 102 | 103 | let primaryColor = DemoDesignSystem.colorPalette.primary.base 104 | 105 | for size in IconSize.previewItems() { 106 | let image = UIImage.template(named: demoImageName, tintColor: primaryColor) 107 | let stack = createStackView(size.0.capitalized, image: image, iconSize: size.1) 108 | sizeStackView.addArrangedSubview(stack) 109 | } 110 | } 111 | 112 | func createStackView(_ text: String, image: UIImage?, iconSize: IconSize = IconSize.medium) -> UIStackView { 113 | let imageView = UIImageView(image: image) 114 | let label = UILabel() 115 | label.applyStyle(labelStyle: AppLabelStyle.subtitle) 116 | label.text = "\(text) Icon" 117 | let iconColorStackView = UIStackView(arrangedSubviews: [label, imageView]) 118 | imageView.anchorIcon(iconSize) 119 | iconColorStackView.axis = .horizontal 120 | iconColorStackView.spacing = Space.p1.rawValue 121 | iconColorStackView.distribution = .fill 122 | iconColorStackView.alignment = .center 123 | view.addSubview(iconColorStackView) 124 | return iconColorStackView 125 | } 126 | } 127 | -------------------------------------------------------------------------------- /Demo/Catalogue/Catalogue/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | $(DEVELOPMENT_LANGUAGE) 7 | CFBundleExecutable 8 | $(EXECUTABLE_NAME) 9 | CFBundleIdentifier 10 | $(PRODUCT_BUNDLE_IDENTIFIER) 11 | CFBundleInfoDictionaryVersion 12 | 6.0 13 | CFBundleName 14 | $(PRODUCT_NAME) 15 | CFBundlePackageType 16 | APPL 17 | CFBundleShortVersionString 18 | 1.0 19 | CFBundleVersion 20 | 1 21 | LSRequiresIPhoneOS 22 | 23 | UILaunchStoryboardName 24 | LaunchScreen 25 | UIMainStoryboardFile 26 | Main 27 | UIRequiredDeviceCapabilities 28 | 29 | armv7 30 | 31 | UISupportedInterfaceOrientations 32 | 33 | UIInterfaceOrientationPortrait 34 | UIInterfaceOrientationLandscapeLeft 35 | UIInterfaceOrientationLandscapeRight 36 | 37 | UISupportedInterfaceOrientations~ipad 38 | 39 | UIInterfaceOrientationPortrait 40 | UIInterfaceOrientationPortraitUpsideDown 41 | UIInterfaceOrientationLandscapeLeft 42 | UIInterfaceOrientationLandscapeRight 43 | 44 | UIAppFonts 45 | 46 | OpenSans-Regular.ttf 47 | OpenSans-Semibold.ttf 48 | OpenSans-LightItalic.ttf 49 | 50 | 51 | 52 | -------------------------------------------------------------------------------- /Demo/Catalogue/Catalogue/LayoutDemoViewController.swift: -------------------------------------------------------------------------------- 1 | // Doric 2 | // 3 | // Copyright (c) 2019 Jay K. 4 | // 5 | // Permission is hereby granted, free of charge, to any person obtaining a copy 6 | // of this software and associated documentation files (the "Software"), to deal 7 | // in the Software without restriction, including without limitation the rights 8 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | // copies of the Software, and to permit persons to whom the Software is 10 | // furnished to do so, subject to the following conditions: 11 | // 12 | // The above copyright notice and this permission notice shall be included in 13 | // all copies or substantial portions of the Software. 14 | // 15 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 21 | // THE SOFTWARE. 22 | 23 | import Doric 24 | import UIKit 25 | 26 | class LayoutDemoViewController: BaseViewController { 27 | override func viewDidLoad() { 28 | super.viewDidLoad() 29 | title = "Layouts & Spacing" 30 | prepareViews() 31 | prepareStyle() 32 | } 33 | 34 | func prepareStyle() { 35 | view.applyStyle(viewStyle: AppViewStyle.main) 36 | } 37 | 38 | func prepareViews() { 39 | let cardView = UIView() 40 | view.addSubview(cardView) 41 | 42 | cardView.backgroundColor = UIColor.white 43 | 44 | cardView.anchorTop(view, constant: .equalTo(Space.p2)) 45 | cardView.anchorLeading(view, constant: .equalTo(Space.p2)) 46 | cardView.anchorTrailing(view, constant: .equalTo(Space.p2)) 47 | 48 | let spaces: [Space] = Space.previewItems() 49 | 50 | // view to keep last labels reference for top constraint 51 | var lastViewReference: UIView? 52 | 53 | for space in spaces { 54 | let textLabel = UILabel() 55 | view.addSubview(textLabel) 56 | textLabel.text = "Leading space \(space.rawValue)" 57 | if lastViewReference == nil { 58 | textLabel.anchorTop(cardView, constant: .equalTo(Space.p1)) 59 | } else { 60 | textLabel.anchorTop(lastViewReference!.bottomAnchor, constant: .equalTo(Space.p1)) 61 | } 62 | 63 | textLabel.anchorTrailing(cardView, constant: .equalTo(Space.p1)) 64 | textLabel.anchorLeading(cardView, constant: .equalTo(space)) 65 | textLabel.applyStyle(labelStyle: AppLabelStyle.title) 66 | textLabel.numberOfLines = 0 67 | textLabel.lineBreakMode = .byWordWrapping 68 | 69 | lastViewReference = textLabel 70 | 71 | textLabel.showGuide(guideline: .leading, color: UIColor.red) 72 | } 73 | 74 | lastViewReference?.anchorBottom(cardView, constant: .equalTo(Space.p1)) 75 | 76 | let button = UIButton() 77 | button.setTitle("Show Borders", for: .normal) 78 | view.addSubview(button) 79 | button.addTarget(self, action: #selector(showBorders), for: .touchUpInside) 80 | button.anchorWidth(cardView) 81 | button.anchorCenterX(cardView) 82 | button.anchorTop(cardView.bottomAnchor, constant: .equalTo(Space.p2)) 83 | button.applyStyle(buttonStyle: AppButtonStyle.bordered) 84 | button.anchorButtonHeight(.medium) 85 | } 86 | 87 | @objc func showBorders() { 88 | UIView.recursiveEnableBorder(view) 89 | } 90 | } 91 | -------------------------------------------------------------------------------- /Demo/Catalogue/Catalogue/MenuItem.swift: -------------------------------------------------------------------------------- 1 | // Doric 2 | // 3 | // Copyright (c) 2019 Jay K. 4 | // 5 | // Permission is hereby granted, free of charge, to any person obtaining a copy 6 | // of this software and associated documentation files (the "Software"), to deal 7 | // in the Software without restriction, including without limitation the rights 8 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | // copies of the Software, and to permit persons to whom the Software is 10 | // furnished to do so, subject to the following conditions: 11 | // 12 | // The above copyright notice and this permission notice shall be included in 13 | // all copies or substantial portions of the Software. 14 | // 15 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 21 | // THE SOFTWARE. 22 | 23 | import UIKit 24 | 25 | // MARK: - List of menu options for Demo, Keeping it as programatically to control order & show/hide items certain items for future demos. 26 | 27 | enum MenuItem: CaseIterable { 28 | case colors 29 | case typography 30 | case scaleChart 31 | case cornerRadius 32 | case borders 33 | case layoutAndSpacing 34 | case iconography 35 | case theme 36 | case style 37 | case toolkit 38 | } 39 | 40 | extension MenuItem { 41 | var display: String { 42 | switch self { 43 | case .colors: 44 | return "Colors" 45 | case .typography: 46 | return "Typography" 47 | case .theme: 48 | return "Theme" 49 | case .scaleChart: 50 | return "Scale Charts" 51 | case .cornerRadius: 52 | return "Corner Radius" 53 | case .borders: 54 | return "Border & Separator" 55 | case .layoutAndSpacing: 56 | return "Layout & Spacing" 57 | case .iconography: 58 | return "Iconography" 59 | case .style: 60 | return "Style" 61 | case .toolkit: 62 | return "Toolkit (Grid, Guideline)" 63 | } 64 | } 65 | } 66 | 67 | extension MenuItem { 68 | var segueIdentifier: String { 69 | switch self { 70 | case .colors: 71 | return "ShowColors" 72 | case .borders, .scaleChart, .cornerRadius: 73 | return "ShowScaleChart" 74 | case .iconography: 75 | return "ShowIconography" 76 | case .typography: 77 | return "ShowTypography" 78 | case .layoutAndSpacing: 79 | return "ShowLayout" 80 | case .toolkit: 81 | return "ShowToolKit" 82 | case .theme: 83 | return "ShowTheme" 84 | case .style: 85 | return "ShowStyle" 86 | } 87 | } 88 | } 89 | -------------------------------------------------------------------------------- /Demo/Catalogue/Catalogue/ScaleChartsViewController.swift: -------------------------------------------------------------------------------- 1 | // Doric 2 | // 3 | // Copyright (c) 2019 Jay K. 4 | // 5 | // Permission is hereby granted, free of charge, to any person obtaining a copy 6 | // of this software and associated documentation files (the "Software"), to deal 7 | // in the Software without restriction, including without limitation the rights 8 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | // copies of the Software, and to permit persons to whom the Software is 10 | // furnished to do so, subject to the following conditions: 11 | // 12 | // The above copyright notice and this permission notice shall be included in 13 | // all copies or substantial portions of the Software. 14 | // 15 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 21 | // THE SOFTWARE. 22 | 23 | import Doric 24 | import UIKit 25 | 26 | class ScaleChartPreviewCell: UITableViewCell { 27 | @IBOutlet var nameLabel: UILabel! 28 | @IBOutlet var valueLabel: UILabel! 29 | @IBOutlet var preview: UIView! 30 | @IBOutlet var previewWidthConstraint: NSLayoutConstraint! 31 | } 32 | 33 | class ScaleChartsViewController: BaseViewController { 34 | @IBOutlet var tableView: UITableView! 35 | 36 | var dataSource: DemoTableViewDataSource! 37 | var demoType: DemoScaleChart = DemoScaleChart.border 38 | 39 | override func viewDidLoad() { 40 | super.viewDidLoad() 41 | 42 | dataSource = demoType.dataSource() 43 | dataSource.prepare() 44 | 45 | tableView.dataSource = dataSource 46 | title = dataSource.title 47 | 48 | prepareStyle() 49 | } 50 | 51 | func prepareStyle() { 52 | view.applyStyle(viewStyle: AppViewStyle.main) 53 | AppTableViewStyle.regular.performStyle(on: tableView) 54 | } 55 | } 56 | 57 | enum DemoScaleChart { 58 | case scaleChart 59 | case border 60 | case cornerRadius 61 | 62 | func dataSource() -> DemoTableViewDataSource { 63 | switch self { 64 | case .border: 65 | return ScaleChartBordersDemoTableViewDataSource() 66 | case .cornerRadius: 67 | return ScaleCornerRadiusDemoTableViewDataSource() 68 | case .scaleChart: 69 | return ScaleChartGroupsDemoTableViewDataSource() 70 | } 71 | } 72 | } 73 | 74 | protocol DemoTableViewDataSource: UITableViewDataSource { 75 | var items: [NamedBorderSize] { get } 76 | var title: String { get } 77 | func prepare() 78 | } 79 | 80 | // MARK: - ScaleChartCornerRadiusDemoTableViewDataSource 81 | 82 | class ScaleCornerRadiusDemoTableViewDataSource: NSObject, DemoTableViewDataSource { 83 | var items: [NamedBorderSize] = [] 84 | var title: String = "" 85 | 86 | func prepare() { 87 | title = "Corner Radius" 88 | items = DemoDesignSystem.cornerRadius.previewItems() 89 | } 90 | 91 | func tableView(_: UITableView, numberOfRowsInSection _: Int) -> Int { 92 | return items.count 93 | } 94 | 95 | // Radius 96 | func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell { 97 | let item = items[indexPath.row] 98 | // swiftlint:disable force_cast 99 | let cell = tableView.dequeueReusableCell(withIdentifier: "ScaleChartPreviewCell", for: indexPath) as! ScaleChartPreviewCell 100 | // swiftlint:enable force_cast 101 | 102 | cell.nameLabel.text = item.0.uppercased() 103 | cell.valueLabel.text = "Corner Radius \(item.1)" 104 | cell.preview.layer.borderWidth = DemoDesignSystem.border.medium // item.1 105 | cell.preview.layer.cornerRadius = item.1 106 | 107 | cell.nameLabel.applyStyle(labelStyle: AppLabelStyle.title) 108 | cell.valueLabel.applyStyle(labelStyle: AppLabelStyle.subtitle) 109 | 110 | cell.preview.backgroundColor = UIColor.clear 111 | 112 | cell.preview.layer.borderColor = DemoDesignSystem.colorPalette.primary.darken1.cgColor 113 | return cell 114 | } 115 | } 116 | 117 | // MARK: - SizeChartBordersDemoTableViewDataSource 118 | 119 | class ScaleChartBordersDemoTableViewDataSource: NSObject, DemoTableViewDataSource { 120 | var items: [NamedBorderSize] = [] 121 | var title: String = "" 122 | 123 | func prepare() { 124 | title = "Borders" 125 | items = DemoDesignSystem.border.previewItems() 126 | } 127 | 128 | func tableView(_: UITableView, numberOfRowsInSection _: Int) -> Int { 129 | return items.count 130 | } 131 | 132 | func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell { 133 | let item = items[indexPath.row] 134 | // swiftlint:disable force_cast 135 | let cell = tableView.dequeueReusableCell(withIdentifier: "ScaleChartPreviewCell", for: indexPath) as! ScaleChartPreviewCell 136 | // swiftlint:enable force_cast 137 | 138 | cell.nameLabel.text = item.0.uppercased() 139 | cell.valueLabel.text = "Border \(item.1)" 140 | cell.preview.layer.borderWidth = item.1 141 | 142 | cell.nameLabel.applyStyle(labelStyle: AppLabelStyle.title) 143 | cell.valueLabel.applyStyle(labelStyle: AppLabelStyle.subtitle) 144 | 145 | cell.preview.backgroundColor = UIColor.clear 146 | cell.preview.layer.borderColor = DemoDesignSystem.colorPalette.primary.darken1.cgColor 147 | return cell 148 | } 149 | } 150 | 151 | // MARK: - SizeChartGroupsDemoTableViewDataSource 152 | 153 | class ScaleChartGroupsDemoTableViewDataSource: NSObject, DemoTableViewDataSource { 154 | var items: [NamedBorderSize] = [] 155 | var title: String = "" 156 | 157 | func prepare() { 158 | title = "Scales" 159 | items = SizeScale.previewItems().sorted(by: { ($0.1 < $1.1) }) 160 | } 161 | 162 | func tableView(_: UITableView, numberOfRowsInSection _: Int) -> Int { 163 | return items.count 164 | } 165 | 166 | func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell { 167 | let item = items[indexPath.row] 168 | // swiftlint:disable force_cast 169 | let cell = tableView.dequeueReusableCell(withIdentifier: "ScaleChartPreviewCell", for: indexPath) as! ScaleChartPreviewCell 170 | // swiftlint:enable force_cast 171 | 172 | cell.nameLabel.text = item.0.uppercased() 173 | cell.valueLabel.text = "Scale \(item.1)" 174 | 175 | cell.nameLabel.applyStyle(labelStyle: AppLabelStyle.title) 176 | cell.valueLabel.applyStyle(labelStyle: AppLabelStyle.subtitle) 177 | 178 | // For demo - We don't need preview for this cell, so reducing priority to allow label to expand 179 | cell.preview.backgroundColor = UIColor.clear 180 | cell.previewWidthConstraint.priority = .defaultLow 181 | return cell 182 | } 183 | } 184 | -------------------------------------------------------------------------------- /Demo/Catalogue/Catalogue/Theme+System.swift: -------------------------------------------------------------------------------- 1 | // Doric 2 | // 3 | // Copyright (c) 2019 Jay K. 4 | // 5 | // Permission is hereby granted, free of charge, to any person obtaining a copy 6 | // of this software and associated documentation files (the "Software"), to deal 7 | // in the Software without restriction, including without limitation the rights 8 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | // copies of the Software, and to permit persons to whom the Software is 10 | // furnished to do so, subject to the following conditions: 11 | // 12 | // The above copyright notice and this permission notice shall be included in 13 | // all copies or substantial portions of the Software. 14 | // 15 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 21 | // THE SOFTWARE. 22 | 23 | import Doric 24 | import UIKit 25 | 26 | // Example 2 themes 27 | 28 | /// DemoPrimaryTheme 29 | struct DemoPrimaryTheme: Theme { 30 | let identifier: String = "theme-1" 31 | let colorPalette: MainColorPalette.Type = DemoColorPalette.self 32 | 33 | struct DemoColorPalette: MainColorPalette { 34 | static var semantic: SemanticColorPalette.Type = DefaultSemanticColorPalette.self 35 | static var grayscale: LargerColorPalette.Type = DefaultGrayScalePalette.self 36 | static let primary: ColorPalette.Type = DoricDemoPrimaryColor.self 37 | static let secondary: ColorPalette.Type = DoricDemoSecondaryColor.self 38 | static let supplimentory: ColorPalette.Type = DoricDemoSupplimantoryColor.self 39 | } 40 | } 41 | 42 | /// DemoSecondaryTheme 43 | struct DemoSecondaryTheme: Theme { 44 | let identifier: String = "theme-2" 45 | let colorPalette: MainColorPalette.Type = DemoColorPalette.self 46 | 47 | struct DemoColorPalette: MainColorPalette { 48 | static let primary: ColorPalette.Type = DoricDemoSecondaryColor.self 49 | static let secondary: ColorPalette.Type = DoricDemoPrimaryColor.self 50 | static let supplimentory: ColorPalette.Type = DoricDemoSupplimantoryColor.self 51 | static var semantic: SemanticColorPalette.Type = DefaultSemanticColorPalette.self 52 | static var grayscale: LargerColorPalette.Type = DefaultGrayScalePalette.self 53 | } 54 | } 55 | -------------------------------------------------------------------------------- /Demo/Catalogue/Catalogue/ThemeDemoViewController.swift: -------------------------------------------------------------------------------- 1 | // Doric 2 | // 3 | // Copyright (c) 2019 Jay K. 4 | // 5 | // Permission is hereby granted, free of charge, to any person obtaining a copy 6 | // of this software and associated documentation files (the "Software"), to deal 7 | // in the Software without restriction, including without limitation the rights 8 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | // copies of the Software, and to permit persons to whom the Software is 10 | // furnished to do so, subject to the following conditions: 11 | // 12 | // The above copyright notice and this permission notice shall be included in 13 | // all copies or substantial portions of the Software. 14 | // 15 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 21 | // THE SOFTWARE. 22 | 23 | import Doric 24 | import Foundation 25 | import UIKit 26 | 27 | class ThemeDemoViewController: BaseViewController { 28 | @IBOutlet var bodyLabel: UILabel! 29 | @IBOutlet var headerLabel: UILabel! 30 | @IBOutlet var primaryColorPreview: UIView! 31 | @IBOutlet var secondaryColorPreview: UIView! 32 | @IBOutlet var primaryButton: UIButton! 33 | @IBOutlet var storyboardButton: UIButton! 34 | 35 | override func viewDidLoad() { 36 | super.viewDidLoad() 37 | 38 | title = "Theme Demo" 39 | 40 | prepareStyle() 41 | } 42 | 43 | override func updateUIOnThemeChange(_: Theme) { 44 | prepareStyle() 45 | } 46 | 47 | func prepareStyle() { 48 | view.applyStyle(viewStyle: AppViewStyle.main) 49 | 50 | // Alternate way to apply brand eaither using extention or enum's method 51 | AppLabelStyle.body.performStyle(on: bodyLabel) 52 | AppLabelStyle.header.performStyle(on: headerLabel) 53 | AppButtonStyle.bordered.performStyle(on: primaryButton) 54 | AppNavigationStyle.regular.performStyle(on: navigationController!.navigationBar) 55 | AppButtonStyle.primary.performStyle(on: storyboardButton) 56 | 57 | primaryColorPreview.backgroundColor = DemoDesignSystem.colorPalette.primary.base 58 | secondaryColorPreview.backgroundColor = DemoDesignSystem.colorPalette.secondary.base 59 | } 60 | 61 | @IBAction func toggleTheme(_: UIButton) { 62 | guard var themeManager = (UIApplication.shared.delegate as? AppDelegate)?.themeManager else { 63 | return 64 | } 65 | themeManager.toggleTheme() 66 | } 67 | } 68 | -------------------------------------------------------------------------------- /Demo/Catalogue/Catalogue/ToolKitViewController.swift: -------------------------------------------------------------------------------- 1 | // Doric 2 | // 3 | // Copyright (c) 2019 Jay K. 4 | // 5 | // Permission is hereby granted, free of charge, to any person obtaining a copy 6 | // of this software and associated documentation files (the "Software"), to deal 7 | // in the Software without restriction, including without limitation the rights 8 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | // copies of the Software, and to permit persons to whom the Software is 10 | // furnished to do so, subject to the following conditions: 11 | // 12 | // The above copyright notice and this permission notice shall be included in 13 | // all copies or substantial portions of the Software. 14 | // 15 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 21 | // THE SOFTWARE. 22 | 23 | import Doric 24 | import UIKit 25 | 26 | class ToolKitViewController: BaseViewController { 27 | var containerView: UIView? 28 | var textLabel: UILabel? 29 | 30 | override func viewDidLoad() { 31 | super.viewDidLoad() 32 | 33 | title = "Toolkit" 34 | 35 | let optionsBarItem = UIBarButtonItem(title: "Options", style: .plain, target: self, action: #selector(showOptions)) 36 | navigationItem.rightBarButtonItem = optionsBarItem 37 | 38 | // By Default show basic guide for debuging 39 | showBasicGuide() 40 | } 41 | 42 | func prepareStyle() { 43 | view.applyStyle(viewStyle: AppViewStyle.main) 44 | } 45 | 46 | override func updateUIOnThemeChange(_: Theme) { 47 | prepareStyle() 48 | showBasicGuide() 49 | } 50 | 51 | func showGraphOrHide() { 52 | Doric.shared.isHidden = !Doric.shared.isHidden 53 | } 54 | 55 | func showAllGuide() { 56 | Doric.shared.isHidden = true 57 | prepareContainerView() 58 | let guidelines: UIView.Guideline = .all 59 | textLabel?.showGuide(guideline: guidelines, color: DemoDesignSystem.colorPalette.white) 60 | } 61 | 62 | func showBasicGuide() { 63 | Doric.shared.isHidden = true 64 | prepareContainerView() 65 | let guidelines: UIView.Guideline = [.leading, .firstBaseline, .bottom] 66 | textLabel?.showGuide(guideline: guidelines, color: DemoDesignSystem.colorPalette.white) 67 | } 68 | 69 | @objc func showOptions() { 70 | let alert = UIAlertController(title: "Select Options", message: nil, preferredStyle: .actionSheet) 71 | let action1Title = Doric.shared.isHidden ? "Show graph" : "Hide graph" 72 | let action1 = UIAlertAction(title: action1Title, style: .default) { _ in 73 | self.showGraphOrHide() 74 | } 75 | 76 | let action2 = UIAlertAction(title: "Show all guides", style: .default) { _ in 77 | self.showAllGuide() 78 | } 79 | 80 | let action3 = UIAlertAction(title: "Show basic guides", style: .default) { _ in 81 | self.showBasicGuide() 82 | } 83 | 84 | let cancel = UIAlertAction(title: "Cancel", style: .cancel) { _ in 85 | } 86 | 87 | alert.addAction(action1) 88 | alert.addAction(action2) 89 | alert.addAction(action3) 90 | alert.addAction(cancel) 91 | presentOptions(alert, barButtonItem: navigationItem.rightBarButtonItem) 92 | } 93 | 94 | func prepareContainerView() { 95 | if containerView != nil { 96 | containerView?.removeFromSuperview() 97 | } 98 | 99 | containerView = UIView() 100 | view.addSubview(containerView!) 101 | 102 | containerView!.backgroundColor = DemoDesignSystem.colorPalette.black 103 | 104 | containerView?.anchorTop(view, constant: .equalTo(Space.p2)) 105 | containerView?.anchorLeading(view, constant: .equalTo(Space.p2)) 106 | containerView?.anchorTrailing(view, constant: .equalTo(Space.p2)) 107 | containerView?.anchorHeight(.equalTo(CardSize.logo)) 108 | 109 | let textLabel = UILabel() 110 | 111 | textLabel.text = "Text" 112 | textLabel.textColor = DemoDesignSystem.colorPalette.white 113 | 114 | // Exception - we need largest font size to display text which covers screen. 115 | textLabel.font = UIFont.systemFont(ofSize: 90.0) 116 | textLabel.sizeToFit() 117 | containerView?.addSubview(textLabel) 118 | textLabel.anchorCenter(containerView) 119 | self.textLabel = textLabel 120 | } 121 | } 122 | -------------------------------------------------------------------------------- /Demo/Catalogue/Catalogue/Typography+AvenirNext.swift: -------------------------------------------------------------------------------- 1 | // Doric 2 | // 3 | // Copyright (c) 2019 Jay K. 4 | // 5 | // Permission is hereby granted, free of charge, to any person obtaining a copy 6 | // of this software and associated documentation files (the "Software"), to deal 7 | // in the Software without restriction, including without limitation the rights 8 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | // copies of the Software, and to permit persons to whom the Software is 10 | // furnished to do so, subject to the following conditions: 11 | // 12 | // The above copyright notice and this permission notice shall be included in 13 | // all copies or substantial portions of the Software. 14 | // 15 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 21 | // THE SOFTWARE. 22 | 23 | import Doric 24 | import UIKit 25 | 26 | /// Avenir Font Enum 27 | enum AvenirNext: String { 28 | case nextMedium = "AvenirNext-Medium" 29 | case demiBold = "AvenirNext-DemiBold" 30 | case regular = "AvenirNext-Regular" 31 | case italic = "AvenirNext-Italic" 32 | } 33 | 34 | public class AvenirNextFont: DynamicTypeFont { 35 | public let dynamicSupportEnabled: Bool = true 36 | public let fonts: [UIFont.TextStyle: FontConvertible] = 37 | [UIFont.TextStyle.caption2: FontDescription(name: AvenirNext.regular.rawValue, size: 9.0), 38 | UIFont.TextStyle.caption1: FontDescription(name: AvenirNext.regular.rawValue, size: 12.0), 39 | UIFont.TextStyle.footnote: FontDescription(name: AvenirNext.italic.rawValue, size: 13.0), 40 | UIFont.TextStyle.subheadline: FontDescription(name: AvenirNext.regular.rawValue, size: 15.0), 41 | UIFont.TextStyle.callout: FontDescription(name: AvenirNext.regular.rawValue, size: 16.0), 42 | UIFont.TextStyle.body: FontDescription(name: AvenirNext.regular.rawValue, size: 17.0), 43 | UIFont.TextStyle.headline: FontDescription(name: AvenirNext.demiBold.rawValue, size: 17.0), 44 | UIFont.TextStyle.title3: FontDescription(name: AvenirNext.nextMedium.rawValue, size: 20.0), 45 | UIFont.TextStyle.title2: FontDescription(name: AvenirNext.nextMedium.rawValue, size: 22.0), 46 | UIFont.TextStyle.title1: FontDescription(name: AvenirNext.nextMedium.rawValue, size: 28.0), 47 | UIFont.TextStyle.largeTitle: FontDescription(name: AvenirNext.regular.rawValue, size: 34.0)] 48 | } 49 | 50 | class DoricDemoTypography: DynamicTypography { 51 | private static let internalFont: AvenirNextFont = AvenirNextFont() 52 | 53 | typealias FontStyle = UIFont.TextStyle 54 | static func font(forTextStyle style: UIFont.TextStyle) -> UIFont { 55 | return internalFont.font(forTextStyle: style) 56 | } 57 | 58 | static func preferredFont(forTextStyle style: UIFont.TextStyle) -> UIFont { 59 | return internalFont.preferredFont(forTextStyle: style) 60 | } 61 | } 62 | -------------------------------------------------------------------------------- /Demo/Catalogue/Catalogue/Typography+Menlo.swift: -------------------------------------------------------------------------------- 1 | // Doric 2 | // 3 | // Copyright (c) 2019 Jay K. 4 | // 5 | // Permission is hereby granted, free of charge, to any person obtaining a copy 6 | // of this software and associated documentation files (the "Software"), to deal 7 | // in the Software without restriction, including without limitation the rights 8 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | // copies of the Software, and to permit persons to whom the Software is 10 | // furnished to do so, subject to the following conditions: 11 | // 12 | // The above copyright notice and this permission notice shall be included in 13 | // all copies or substantial portions of the Software. 14 | // 15 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 21 | // THE SOFTWARE. 22 | 23 | import Doric 24 | import UIKit 25 | 26 | /// Example Custom Text 3 styles header, body, instruction 27 | enum AppContentTextStyle: String { 28 | case contentHeader 29 | case contentBody 30 | case contentInstruction 31 | } 32 | 33 | /// Menlo font with Custom Text Style, Need to implement `Font` protocol 34 | class MenloFont: NSObject, Font { 35 | typealias CustomFontStyle = AppContentTextStyle 36 | let fonts: [AppContentTextStyle: FontConvertible] = 37 | [AppContentTextStyle.contentInstruction: FontDescription(name: "Menlo-Italic", size: 12.0), 38 | AppContentTextStyle.contentBody: FontDescription(name: "Menlo-Regular", size: 15.0), 39 | AppContentTextStyle.contentHeader: FontDescription(name: "Menlo-Bold", size: 17.0)] 40 | } 41 | -------------------------------------------------------------------------------- /Demo/Catalogue/Catalogue/Typography+OpenSans.swift: -------------------------------------------------------------------------------- 1 | // Doric 2 | // 3 | // Copyright (c) 2019 Jay K. 4 | // 5 | // Permission is hereby granted, free of charge, to any person obtaining a copy 6 | // of this software and associated documentation files (the "Software"), to deal 7 | // in the Software without restriction, including without limitation the rights 8 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | // copies of the Software, and to permit persons to whom the Software is 10 | // furnished to do so, subject to the following conditions: 11 | // 12 | // The above copyright notice and this permission notice shall be included in 13 | // all copies or substantial portions of the Software. 14 | // 15 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 21 | // THE SOFTWARE. 22 | 23 | import Doric 24 | import UIKit 25 | 26 | /// Open Sans Style 27 | enum OpenSansStyle: String { 28 | case contentHeading 29 | case contentBody 30 | case contentInstruction 31 | case brand 32 | } 33 | 34 | /// Open sans - External fonts 35 | class OpenSansFont: NSObject, DynamicTypeCustomTextStyleFont { 36 | typealias CustomFontStyle = OpenSansStyle 37 | let fonts: [OpenSansStyle: FontConvertible] = 38 | [OpenSansStyle.contentInstruction: FontDescription(name: "OpenSansLight-Italic", size: 9.0), 39 | OpenSansStyle.contentBody: FontDescription(name: "OpenSans", size: 17.0), 40 | OpenSansStyle.contentHeading: FontDescription(name: "OpenSans-Semibold", size: 17.0), 41 | OpenSansStyle.brand: FontDescription(name: "OpenSans", size: 15.0)] 42 | 43 | func preferredFont(forTextStyle textStyle: CustomFontStyle) -> UIFont { 44 | return preferredFont(forTextStyle: textStyle, maximumPointSize: 1000.0, compatibleWith: nil) 45 | } 46 | 47 | func preferredFont(forTextStyle textStyle: CustomFontStyle, 48 | maximumPointSize _: CGFloat, 49 | compatibleWith traitCollection: UITraitCollection?) -> UIFont { 50 | if let desc = fonts[textStyle] as? FontDescription { 51 | let scaledSize = UIFontMetrics.default.scaledValue(for: desc.size, compatibleWith: traitCollection) 52 | return UIFont(name: desc.name, size: scaledSize) ?? UIFont.default 53 | } 54 | return UIFont.default // Fallback fonts 55 | } 56 | } 57 | 58 | // External Font 'OpenSans' 59 | class OpenSansTypography: DynamicTypography { 60 | private static let internalFont: OpenSansFont = OpenSansFont() 61 | typealias FontStyle = OpenSansStyle 62 | static func font(forTextStyle style: OpenSansStyle) -> UIFont { 63 | return internalFont.font(forTextStyle: style) 64 | } 65 | 66 | static func preferredFont(forTextStyle style: OpenSansStyle) -> UIFont { 67 | return internalFont.preferredFont(forTextStyle: style) 68 | } 69 | } 70 | 71 | extension OpenSansTypography { 72 | static func namedTypography() -> [NameFonts] { 73 | var fonts: [NameFonts] = [] 74 | fonts.append(("brand", preferredFont(forTextStyle: .brand))) 75 | fonts.append(("contentBody", preferredFont(forTextStyle: .contentBody))) 76 | fonts.append(("contentHeading", preferredFont(forTextStyle: .contentHeading))) 77 | fonts.append(("contentInstruction", preferredFont(forTextStyle: .contentInstruction))) 78 | return fonts 79 | } 80 | } 81 | -------------------------------------------------------------------------------- /Demo/Catalogue/Catalogue/TypographyDemoViewController.swift: -------------------------------------------------------------------------------- 1 | // Doric 2 | // 3 | // Copyright (c) 2019 Jay K. 4 | // 5 | // Permission is hereby granted, free of charge, to any person obtaining a copy 6 | // of this software and associated documentation files (the "Software"), to deal 7 | // in the Software without restriction, including without limitation the rights 8 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | // copies of the Software, and to permit persons to whom the Software is 10 | // furnished to do so, subject to the following conditions: 11 | // 12 | // The above copyright notice and this permission notice shall be included in 13 | // all copies or substantial portions of the Software. 14 | // 15 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 21 | // THE SOFTWARE. 22 | 23 | import Doric 24 | import UIKit 25 | 26 | class TypographyPreviewCell: UITableViewCell { 27 | @IBOutlet var nameLabel: UILabel! 28 | @IBOutlet var valueLabel: UILabel! 29 | } 30 | 31 | class TypographyDemoViewController: BaseViewController { 32 | @IBOutlet var tableView: UITableView! 33 | 34 | var fonts: [NameFonts] = DemoDesignSystem.typography.namedTypography().sorted { (font1, font2) -> Bool in 35 | return font1.1.pointSize < font2.1.pointSize 36 | } 37 | 38 | override func viewDidLoad() { 39 | super.viewDidLoad() 40 | 41 | title = "Typography" 42 | 43 | prepareStyle() 44 | } 45 | 46 | func prepareStyle() { 47 | view.applyStyle(viewStyle: AppViewStyle.main) 48 | AppTableViewStyle.regular.performStyle(on: tableView) 49 | } 50 | } 51 | 52 | extension TypographyDemoViewController: UITableViewDelegate, UITableViewDataSource { 53 | func tableView(_: UITableView, numberOfRowsInSection _: Int) -> Int { 54 | return fonts.count 55 | } 56 | 57 | func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell { 58 | let font = fonts[indexPath.row] 59 | // swiftlint:disable force_cast 60 | let cell = tableView.dequeueReusableCell(withIdentifier: "TypographyPreviewCell", for: indexPath) as! TypographyPreviewCell 61 | // swiftlint:enable force_cast 62 | 63 | cell.nameLabel.text = font.0 + " - [\(font.1.pointSize) pointSize]" 64 | cell.nameLabel.applyStyle(labelStyle: AppLabelStyle.title) 65 | cell.valueLabel.text = "\(font.1.familyName) \(font.1.fontName)" 66 | cell.valueLabel.font = font.1 67 | cell.valueLabel.textColor = DemoDesignSystem.colorPalette.grayscale.darken2 68 | return cell 69 | } 70 | } 71 | -------------------------------------------------------------------------------- /Demo/Catalogue/Catalogue/Utility.swift: -------------------------------------------------------------------------------- 1 | // Doric 2 | // 3 | // Copyright (c) 2019 Jay K. 4 | // 5 | // Permission is hereby granted, free of charge, to any person obtaining a copy 6 | // of this software and associated documentation files (the "Software"), to deal 7 | // in the Software without restriction, including without limitation the rights 8 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | // copies of the Software, and to permit persons to whom the Software is 10 | // furnished to do so, subject to the following conditions: 11 | // 12 | // The above copyright notice and this permission notice shall be included in 13 | // all copies or substantial portions of the Software. 14 | // 15 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 21 | // THE SOFTWARE. 22 | 23 | import Doric 24 | import UIKit 25 | 26 | /// Helpers for demo 27 | 28 | extension Date { 29 | static var displayDateString: String { 30 | return DateFormatter.localizedString(from: Date(), dateStyle: .long, timeStyle: .short) 31 | } 32 | } 33 | 34 | // Example How to create custom space 35 | 36 | enum CustomSpace: CGFloat, LayoutValueRepresentable { 37 | case space1 = 4.0 38 | case space2 = 8.0 39 | case space3 = 12.0 40 | case space4 = 16.0 41 | 42 | static func previewItems() -> [CustomSpace] { 43 | return [CustomSpace.space1, CustomSpace.space2, CustomSpace.space3, CustomSpace.space4] 44 | } 45 | } 46 | 47 | // Example how to create style in storyboard 48 | 49 | @IBDesignable public class CustomStyledButton: UIButton { 50 | @IBInspectable var doricStyle: String? { 51 | get { 52 | return nil 53 | } set(newValue) { 54 | if let value = newValue, let storyboardStyle = StoryboardButtonStyle(rawValue: value) { 55 | storyboardStyle.performStyle(on: self) 56 | } 57 | } 58 | } 59 | } 60 | 61 | /// StoryboardButtonStyle 62 | /// 63 | /// - actionButton: style for action button 64 | enum StoryboardButtonStyle: String { 65 | case actionButton 66 | } 67 | 68 | // MARK: - StoryboardButtonStyle 69 | 70 | extension StoryboardButtonStyle: ButtonStyle { 71 | public func performStyle(on button: UIButton) { 72 | switch self { 73 | case .actionButton: 74 | let textColor = DemoDesignSystem.colorPalette.grayscale.lighten2 75 | button.backgroundColor = DemoDesignSystem.colorPalette.primary.base 76 | button.layer.cornerRadius = DemoDesignSystem.cornerRadius.medium 77 | button.setTitleColor(textColor, for: .normal) 78 | button.titleLabel?.font = DemoDesignSystem.typography.font(forTextStyle: .body) 79 | } 80 | } 81 | } 82 | 83 | extension UITableView { 84 | func addEmptyFooter() { 85 | tableFooterView = UIView(frame: CGRect(x: 0, y: 0, width: 1, height: 1)) 86 | } 87 | } 88 | -------------------------------------------------------------------------------- /Demo/Catalogue/Catalogue/open-sans/OpenSans-Bold.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jayeshk/Doric/2629fb2d1328fdbf7d76a8583e3931caa8238168/Demo/Catalogue/Catalogue/open-sans/OpenSans-Bold.ttf -------------------------------------------------------------------------------- /Demo/Catalogue/Catalogue/open-sans/OpenSans-BoldItalic.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jayeshk/Doric/2629fb2d1328fdbf7d76a8583e3931caa8238168/Demo/Catalogue/Catalogue/open-sans/OpenSans-BoldItalic.ttf -------------------------------------------------------------------------------- /Demo/Catalogue/Catalogue/open-sans/OpenSans-ExtraBold.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jayeshk/Doric/2629fb2d1328fdbf7d76a8583e3931caa8238168/Demo/Catalogue/Catalogue/open-sans/OpenSans-ExtraBold.ttf -------------------------------------------------------------------------------- /Demo/Catalogue/Catalogue/open-sans/OpenSans-ExtraBoldItalic.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jayeshk/Doric/2629fb2d1328fdbf7d76a8583e3931caa8238168/Demo/Catalogue/Catalogue/open-sans/OpenSans-ExtraBoldItalic.ttf -------------------------------------------------------------------------------- /Demo/Catalogue/Catalogue/open-sans/OpenSans-Italic.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jayeshk/Doric/2629fb2d1328fdbf7d76a8583e3931caa8238168/Demo/Catalogue/Catalogue/open-sans/OpenSans-Italic.ttf -------------------------------------------------------------------------------- /Demo/Catalogue/Catalogue/open-sans/OpenSans-Light.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jayeshk/Doric/2629fb2d1328fdbf7d76a8583e3931caa8238168/Demo/Catalogue/Catalogue/open-sans/OpenSans-Light.ttf -------------------------------------------------------------------------------- /Demo/Catalogue/Catalogue/open-sans/OpenSans-LightItalic.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jayeshk/Doric/2629fb2d1328fdbf7d76a8583e3931caa8238168/Demo/Catalogue/Catalogue/open-sans/OpenSans-LightItalic.ttf -------------------------------------------------------------------------------- /Demo/Catalogue/Catalogue/open-sans/OpenSans-Regular.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jayeshk/Doric/2629fb2d1328fdbf7d76a8583e3931caa8238168/Demo/Catalogue/Catalogue/open-sans/OpenSans-Regular.ttf -------------------------------------------------------------------------------- /Demo/Catalogue/Catalogue/open-sans/OpenSans-Semibold.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jayeshk/Doric/2629fb2d1328fdbf7d76a8583e3931caa8238168/Demo/Catalogue/Catalogue/open-sans/OpenSans-Semibold.ttf -------------------------------------------------------------------------------- /Demo/Catalogue/Catalogue/open-sans/OpenSans-SemiboldItalic.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jayeshk/Doric/2629fb2d1328fdbf7d76a8583e3931caa8238168/Demo/Catalogue/Catalogue/open-sans/OpenSans-SemiboldItalic.ttf -------------------------------------------------------------------------------- /Doric.podspec: -------------------------------------------------------------------------------- 1 | Pod::Spec.new do |s| 2 | s.name = "Doric" 3 | s.version = "1.0.0" 4 | s.summary = "Doric is Design System foundation written in Swift. Protocol oriented and type safe scalable framework to create Design System." 5 | s.homepage = "https://github.com/jayeshk/Doric" 6 | s.license = { :type => 'MIT', :file => 'LICENSE' } 7 | s.author = { "Jay K." => "mobilejay5@gmail.com" } 8 | s.source = { :git => "https://github.com/jayeshk/Doric.git", :tag => s.version.to_s } 9 | s.ios.deployment_target = '11.0' 10 | s.requires_arc = true 11 | s.source_files = 'Source/*.{swift}' 12 | s.resources = 'Source/**/*.{png}' 13 | s.frameworks = 'UIKit' 14 | s.swift_version = "4.2" 15 | 16 | end 17 | -------------------------------------------------------------------------------- /Doric.xcodeproj/project.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /Doric.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | IDEDidComputeMac32BitWarning 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /Doric.xcodeproj/xcshareddata/xcschemes/Doric.xcscheme: -------------------------------------------------------------------------------- 1 | 2 | 5 | 8 | 9 | 15 | 21 | 22 | 23 | 24 | 25 | 30 | 31 | 32 | 33 | 34 | 35 | 45 | 46 | 52 | 53 | 54 | 55 | 56 | 57 | 63 | 64 | 70 | 71 | 72 | 73 | 75 | 76 | 79 | 80 | 81 | -------------------------------------------------------------------------------- /Doric.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /Doric.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | IDEDidComputeMac32BitWarning 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Doric 2 | 3 | Copyright (c) 2019 Jay K. 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in 13 | all copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 21 | THE SOFTWARE. 22 | -------------------------------------------------------------------------------- /PULL_REQUEST_TEMPLATE.md: -------------------------------------------------------------------------------- 1 | Before you open the request please review the following guidelines and tips to 2 | help it be more easily integrated: 3 | 4 | - **Describe the scope of your change i.e. what the change does and what parts 5 | of the code were modified.** This will help us understand any risks of integrating 6 | the code. 7 | 8 | - **Describe any known limitations with your change.** For example if the change 9 | doesn't apply to a supported platform of the library please mention it. 10 | 11 | - **Please run any tests or examples that can exercise your modified code.** We 12 | strive to not break users of the code and running tests/examples helps with this 13 | process. 14 | 15 | 16 | Thank you again for contributing! 17 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | 2 | 3 | ![Doric: Design System Foundation in Swift](https://raw.githubusercontent.com/jayeshk/Doric/master/doric.png) 4 | 5 | [![Build Status](https://travis-ci.com/jayeshk/Doric.svg?branch=master)](https://travis-ci.com/jayeshk/Doric) [![CocoaPods Compatible](https://img.shields.io/cocoapods/v/Doric.svg)](https://img.shields.io/cocoapods/v/Doric.svg) [![Carthage compatible](https://img.shields.io/badge/Carthage-compatible-red.svg?style=flat)](https://github.com/Carthage/Carthage) [![Platform](https://img.shields.io/cocoapods/p/Doric.svg?style=flat)](https://github.com/jayeshk/Doric) 6 | ![Documentation](https://github.com/jayeshk/Doric/blob/master/docs/badge.svg) 7 | 8 | # **Doric: Design System Foundation** 9 | 10 | Design System foundation written in Swift. Protocol oriented, type safe, scalable framework for iOS. 11 | 12 | - [Features](#features) 13 | - [Requirements](#requirements) 14 | - [Contribute](#contribute) 15 | - [Installation](#installation) 16 | - [Usage](./Documentation/Usage.md) 17 | - [FAQ](#faq) 18 | - [Credits](#credits) 19 | - [License](#license) 20 | 21 | ## Features 22 | 23 | - [x] Typography 24 | - [x] Iconography 25 | - [x] Colour Palette 26 | - [x] Dynamic scalable font support 27 | - [x] Auto layout 28 | - [x] Gradients, Shadows, Borders and other scales 29 | - [x] Layout spacing 30 | - [x] Themes 31 | - [x] UI Debugging helpers 32 | - [x] [API Document](https://jayeshk.github.io/Doric/usage.html) & [Usage Documentation](Documentation/Usage.md) 33 | 34 | ## Sketch Plugin 35 | 36 | - See [DoricSnippet - BETA](https://github.com/jayeshk/DoricSnippet) 37 | - Generates Swift code snippets for Doric framework. 38 | 39 | ## Roadmap 40 | 41 | > *Not in specific orders to achieve it.* 42 | 43 | - [ ] Add debugging tools (Ruler etc.) [In progress] 44 | - [ ] Expand framework to create more Styles 45 | - [ ] Colour processing utilities 46 | - [ ] Trait based layouts (UITraitCollection) [In progress] 47 | - [ ] Accessibility for colour palettes 48 | - [x] Sketch plugin to generate palette. [Try here](https://github.com/jayeshk/DoricSnippet) 49 | 50 | ## [Usage Guide](https://jayeshk.github.io/Doric/usage.html) 51 | - See documentation 52 | ## Requirements 53 | 54 | - iOS 11.0+ 55 | - Xcode 10.2+ 56 | - Swift 5 57 | 58 | ## Demo 59 | ![Preview](https://raw.githubusercontent.com/jayeshk/Doric/master/demo-screenshot.png) ![Preview](https://raw.githubusercontent.com/jayeshk/Doric/master/screens-preview.gif) 60 | 61 | ## Installation 62 | 63 | ### CocoaPods 64 | 65 | [CocoaPods](https://cocoapods.org) is an application level dependency manager for the Objective-C, Swift and any other languages that run on the Objective-C runtime that provides a standard format for managing external libraries. For usage and installation instructions visit [site](https://cocoapods.org) 66 | 67 | To integrate `Doric` using CocoaPods, specify it in your `Podfile`: 68 | 69 | ```ruby 70 | pod 'Doric', '~> 1.0.0' 71 | ``` 72 | 73 | ### Carthage 74 | 75 | [Carthage](https://github.com/Carthage/Carthage) builds your dependencies and provides you with binary frameworks, but you retain full control over your project structure and setup. Carthage does not automatically modify your project files or your build settings. 76 | 77 | . To integrate `Doric` into your Xcode project using Carthage, specify it in your `Cartfile`: 78 | 79 | ```ogdl 80 | github "jayeshk/Doric" ~> 1.0.0 81 | ``` 82 | 83 | ### Manually 84 | 85 | If you can integrate project manually as below using git submodule 86 | 87 | #### Embedded Framework 88 | 89 | - Open up Terminal, `cd` into your top-level project directory, and run the following command "if" your project is not initialised as a git repository: 90 | 91 | ```bash 92 | $ git init 93 | ``` 94 | 95 | - Add Doric as a git submodule by running the following command: 96 | 97 | ```bash 98 | $ git submodule add https://github.com/jayeshk/Doric.git 99 | ``` 100 | 101 | - Open the new `Doric` folder and drag the `Doric.xcodeproj` into the Project Navigator. 102 | 103 | > It should appear nested underneath your application's blue project icon. Whether it is above or below all the other Xcode groups does not matter. 104 | 105 | - Select the `Doric.xcodeproj` in the Project Navigator and verify the deployment target matches that of your application target. 106 | - Next, select your application project in the Project Navigator to navigate to the target configuration window and select the application target under the "Targets" heading in the sidebar. 107 | - In the tab bar at the top of that window, open the "General" panel. 108 | - Click on the `+` button under the "Embedded Binaries" section. 109 | - You will see `Doric.framework` nested inside a `Products` folder. Select the `Doric.framework` for iOS. 110 | 111 | > You can verify which one you selected by inspecting the build log for your project. The build target for `Doric` will be listed as `Doric`. 112 | 113 | > `Doric.framework` is automagically added as a target dependency, linked framework and embedded framework in a copy files build phase which is all you need to build on the simulator and a device. 114 | 115 | 116 | ## Contribute 117 | 118 | Doric is open to contribute, see contribution notes. 119 | - If you **want to contribute**, submit a pull request. 120 | - If you **found a bug**, open an issue. 121 | - If you need **help with a feature or need to discuss best practices** please see **usage document** , still anything to discuss contact me (doricdesignsystem@gmail.com). 122 | 123 | ## FAQ 124 | 125 | #### **About Doric name?** 126 | 127 | The Doric order was one of the three orders of ancient Greek and later Roman architecture, Doric is named based [Doric_order](https://en.wikipedia.org/wiki/Doric_order). Hence provides pillars for your digital products. 128 | 129 | #### **Why Design System required?** 130 | 131 | As the number of devices screen variants and environments are increasing, so there is need to create scalable interface Design Systems. 132 | 133 | Doric's primary goal is to create a system which allows you to manage design at scale for iOS. Consistency, scalability and efficiency across app are focused areas. See [Awesome Design Systems](https://github.com/alexpate/awesome-design-systems) 134 | 135 | #### **It is required to implement all parts of Doric?** 136 | 137 | Doric provides various building blocks to implement interface. All blocks can be used independently or can be composed as needed. For example your app can use Typography only or Color Palettes. Better practice would be compose all them into single Design System. 138 | 139 | It also allows you to use any of these blocks with other third part frameworks. For example Spacing and Layout can be used any other third party frameworks. 140 | 141 | Since it protocol oriented framework you can further extended any of section and customise it. Doric comes with few default implementations. See more for [usage guide](Documentation/Usage.md) 142 | 143 | ## Credits 144 | 145 | `Doric` is influenced by various Design System guidelines and many *stackoverflow* posts. 146 | 147 | Major source of inspiration [Atomic Design](http://atomicdesign.bradfrost.com/) 148 | 149 | *Brad Frost, author of Atomic Design : “comprehensive collection of the bits and pieces that make up your interface”.* 150 | 151 | --- 152 | - [OpenSans Fonts](./Demo/Catalogue/Catalogue/open-sans/) 153 | 154 | ## License 155 | 156 | `Doric` is released under the MIT license. See LICENSE for details. 157 | -------------------------------------------------------------------------------- /Source/Bundle+Extension.swift: -------------------------------------------------------------------------------- 1 | // Doric 2 | // 3 | // Copyright (c) 2019 Jay K. 4 | // 5 | // Permission is hereby granted, free of charge, to any person obtaining a copy 6 | // of this software and associated documentation files (the "Software"), to deal 7 | // in the Software without restriction, including without limitation the rights 8 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | // copies of the Software, and to permit persons to whom the Software is 10 | // furnished to do so, subject to the following conditions: 11 | // 12 | // The above copyright notice and this permission notice shall be included in 13 | // all copies or substantial portions of the Software. 14 | // 15 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 21 | // THE SOFTWARE. 22 | 23 | import UIKit 24 | 25 | public extension Bundle { 26 | /// Find bundle for current framework 27 | static var moduleBundle: Bundle? { 28 | let bundle = Bundle(for: Doric.self) 29 | if let path = bundle.path(forResource: "Doric", ofType: "bundle") { 30 | return Bundle(path: path) 31 | } 32 | return bundle 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /Source/CardView.swift: -------------------------------------------------------------------------------- 1 | // Doric 2 | // 3 | // Copyright (c) 2019 Jay K. 4 | // 5 | // Permission is hereby granted, free of charge, to any person obtaining a copy 6 | // of this software and associated documentation files (the "Software"), to deal 7 | // in the Software without restriction, including without limitation the rights 8 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | // copies of the Software, and to permit persons to whom the Software is 10 | // furnished to do so, subject to the following conditions: 11 | // 12 | // The above copyright notice and this permission notice shall be included in 13 | // all copies or substantial portions of the Software. 14 | // 15 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 21 | // THE SOFTWARE. 22 | 23 | import UIKit 24 | 25 | /// Create shadows card 'layer' view 26 | open class CardView: UIView { 27 | /// cornerRadius of view, by default 4.0 28 | open var cornerRadius: CGFloat = 4.0 29 | 30 | /// shadowOffsetWidth by default 0.0 31 | open var shadowOffsetWidth: CGFloat = 0.0 32 | 33 | /// shadowOffsetHeight by default 2.0 34 | open var shadowOffsetHeight: CGFloat = 2.0 35 | 36 | /// shadowColor, by default black 37 | open var shadowColor: UIColor = UIColor.black 38 | 39 | /// shadowOpacity, by default 0.5 40 | open var shadowOpacity: Float = 0.5 41 | 42 | open override func layoutSubviews() { 43 | layer.cornerRadius = cornerRadius 44 | layer.masksToBounds = false 45 | layer.shadowColor = shadowColor.cgColor 46 | layer.shadowOffset = CGSize(width: shadowOffsetWidth, height: shadowOffsetHeight) 47 | layer.shadowOpacity = shadowOpacity 48 | layer.shadowPath = UIBezierPath(roundedRect: bounds, cornerRadius: cornerRadius).cgPath 49 | } 50 | } 51 | -------------------------------------------------------------------------------- /Source/Colors.swift: -------------------------------------------------------------------------------- 1 | // Doric 2 | // 3 | // Copyright (c) 2019 Jay K. 4 | // 5 | // Permission is hereby granted, free of charge, to any person obtaining a copy 6 | // of this software and associated documentation files (the "Software"), to deal 7 | // in the Software without restriction, including without limitation the rights 8 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | // copies of the Software, and to permit persons to whom the Software is 10 | // furnished to do so, subject to the following conditions: 11 | // 12 | // The above copyright notice and this permission notice shall be included in 13 | // all copies or substantial portions of the Software. 14 | // 15 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 21 | // THE SOFTWARE. 22 | 23 | import UIKit 24 | 25 | /// LightenColorSet, represents lighter colors of base color. 26 | public protocol LightenColorSet { 27 | /// Ligher color of base color. 28 | static var lighten1: UIColor { get } 29 | 30 | /// Ligher color of base color. 31 | static var lighten2: UIColor { get } 32 | } 33 | 34 | /// DarkenColorSet, represents darker colors of base color. 35 | public protocol DarkenColorSet { 36 | /// Darker color of base color. 37 | static var darken1: UIColor { get } 38 | 39 | /// Darker color of base color. 40 | static var darken2: UIColor { get } 41 | } 42 | 43 | /// LightenColorSet, represents lighter colors of base color. 44 | public protocol ExtendedLightenColorSet { 45 | /// Ligher color of base color. 46 | static var lighten3: UIColor { get } 47 | 48 | /// Ligher color of base color. 49 | static var lighten4: UIColor { get } 50 | } 51 | 52 | /// ExtendedDarkenColorSet, represents extedend darker colors of base color. 53 | public protocol ExtendedDarkenColorSet { 54 | /// Darker color of base color. 55 | static var darken3: UIColor { get } 56 | 57 | /// Darker color of base color. 58 | static var darken4: UIColor { get } 59 | } 60 | 61 | /// Color which represents base color, other palettes creates lighter and darker colors of base color. 62 | public protocol Color { 63 | /// represents base color 64 | static var base: UIColor { get } 65 | } 66 | 67 | /// `ColorPalette` represents base color with set of lighter and darker colors of base, total 5 colors (shades and tints) are represented by `ColorPalette`. 68 | public protocol ColorPalette: Color, LightenColorSet, DarkenColorSet {} 69 | 70 | /// LargerColorPalette represents base color with set of lighter and darker colors of base, total 9 colors (shades and tints) are represented by `ColorPalette`. 71 | /// 72 | /// Use it when larger set of lighter and darker colors are required. 73 | public protocol LargerColorPalette: ColorPalette, ExtendedLightenColorSet, ExtendedDarkenColorSet {} 74 | 75 | // MARK: - ColorPalette 76 | 77 | public extension ColorPalette { 78 | /// Default darker by 0.25 of base color. 79 | static var darken1: UIColor { 80 | return base.darker(by: 0.25) 81 | } 82 | 83 | /// Default darker by 0.50 of base color. 84 | static var darken2: UIColor { 85 | return base.darker(by: 0.50) 86 | } 87 | 88 | /// Default lighter by 0.25 of base color. 89 | static var lighten1: UIColor { 90 | return base.lighter(by: 0.25) 91 | } 92 | 93 | /// Default ligher by 0.50 of base color. 94 | static var lighten2: UIColor { 95 | return base.lighter(by: 0.50) 96 | } 97 | } 98 | 99 | // MARK: - LargerColorPalette 100 | 101 | public extension LargerColorPalette { 102 | /// Default darker by 0.75 of base color. 103 | static var darken3: UIColor { 104 | return base.darker(by: 0.75) 105 | } 106 | 107 | /// Default darker by 0.90 of base color. 108 | static var darken4: UIColor { 109 | return base.darker(by: 0.90) 110 | } 111 | 112 | /// Default lighter by 0.75 of base color. 113 | static var lighten3: UIColor { 114 | return base.lighter(by: 0.75) 115 | } 116 | 117 | /// Default lighter by 0.90 of base color. 118 | static var lighten4: UIColor { 119 | return base.lighter(by: 0.90) 120 | } 121 | } 122 | 123 | // MARK: - 124 | 125 | /// Semantic color palette, used for messaging. Used to deliver information about success, error, warning. 126 | /// 127 | /// Generally red for errors, green for success, yellow or organge for warning, blue or gray for informational messages. 128 | public protocol SemanticColorPalette { 129 | /// Error colors. 130 | static var error: ColorPalette.Type { get } 131 | 132 | /// Warning colors. 133 | static var warning: ColorPalette.Type { get } 134 | 135 | /// Success colors. 136 | static var success: ColorPalette.Type { get } 137 | 138 | /// Info/Nuetral colors. 139 | static var info: ColorPalette.Type { get } 140 | } 141 | 142 | // MARK: - 143 | 144 | /// A color palette which contains primary, secondary and supplimentory colors with their darker and lighter color sets. 145 | /// Also contains default semantic and grayscale palette. 146 | public protocol MainColorPalette { 147 | /// primary color palette. 148 | static var primary: ColorPalette.Type { get } 149 | 150 | /// secondary color palette. 151 | static var secondary: ColorPalette.Type { get } 152 | 153 | /// supplimentory color palette. 154 | static var supplimentory: ColorPalette.Type { get } 155 | 156 | /// semantic color palette. 157 | static var semantic: SemanticColorPalette.Type { get } 158 | 159 | /// grayscale color paletter. 160 | static var grayscale: LargerColorPalette.Type { get } 161 | } 162 | 163 | // MARK: - MainColorPalette 164 | 165 | public extension MainColorPalette { 166 | /// Default white color. 167 | static var white: UIColor { return UIColor.white } 168 | 169 | /// Default back color. 170 | static var black: UIColor { return UIColor.black } 171 | 172 | /// Default clear color. 173 | static var clear: UIColor { return UIColor.clear } 174 | } 175 | -------------------------------------------------------------------------------- /Source/Debug+Preview.swift: -------------------------------------------------------------------------------- 1 | // Doric 2 | // 3 | // Copyright (c) 2019 Jay K. 4 | // 5 | // Permission is hereby granted, free of charge, to any person obtaining a copy 6 | // of this software and associated documentation files (the "Software"), to deal 7 | // in the Software without restriction, including without limitation the rights 8 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | // copies of the Software, and to permit persons to whom the Software is 10 | // furnished to do so, subject to the following conditions: 11 | // 12 | // The above copyright notice and this permission notice shall be included in 13 | // all copies or substantial portions of the Software. 14 | // 15 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 21 | // THE SOFTWARE. 22 | 23 | import UIKit 24 | 25 | // Typealias 26 | public typealias NamedBorderSize = (String, CGFloat) 27 | public typealias NameFonts = (String, UIFont) 28 | 29 | public extension Scale { 30 | /// Debug helper methods, to preview items for this collection 31 | /// 32 | /// Only for debuging. 33 | /// - Returns: all items 34 | static func previewItems() -> [NamedBorderSize] { 35 | return [("small", Self.small), 36 | ("medium", Self.medium), 37 | ("large", Self.large)] 38 | } 39 | } 40 | 41 | public extension FullScale { 42 | /// Debug helper methods, to preview items for this collection 43 | /// 44 | /// Only for debuging. 45 | /// - Returns: all items 46 | static func previewItems() -> [NamedBorderSize] { 47 | return [("small", Self.small), 48 | ("medium", Self.medium), 49 | ("large", Self.large), 50 | ("extraSmall", Self.extraSmall), 51 | ("extraLarge", Self.extraLarge), 52 | ("extraExtraLarge", Self.extraExtraLarge), 53 | ("extraExtraExtraLarge", Self.extraExtraExtraLarge)] 54 | } 55 | } 56 | 57 | public extension Space { 58 | static func previewItems() -> [Space] { 59 | return [.p0, .p1, .p2, .p3, .p4, .p5, .p6, .p7, .p8] 60 | } 61 | } 62 | 63 | // For debug 64 | 65 | public extension Typography { 66 | /// Debug helper methods, to preview items for this collection 67 | /// 68 | /// Only for debuging. 69 | /// - Returns: all items 70 | static func previewItems() -> [NameFonts] { 71 | return [] 72 | } 73 | } 74 | 75 | public extension SystemTypography { 76 | /// Debug helper methods, to preview items for this collection 77 | /// 78 | /// Only for debuging. 79 | /// - Returns: all items 80 | static func previewItems() -> [NameFonts] { 81 | var fonts: [NameFonts] = [] 82 | fonts.append(("body", preferredFont(forTextStyle: .body))) 83 | fonts.append(("title1", preferredFont(forTextStyle: .title1))) 84 | fonts.append(("title2", preferredFont(forTextStyle: .title2))) 85 | fonts.append(("title3", preferredFont(forTextStyle: .title3))) 86 | fonts.append(("headline", preferredFont(forTextStyle: .headline))) 87 | fonts.append(("subheadline", preferredFont(forTextStyle: .subheadline))) 88 | fonts.append(("callout", preferredFont(forTextStyle: .callout))) 89 | fonts.append(("footnote", preferredFont(forTextStyle: .footnote))) 90 | fonts.append(("caption1", preferredFont(forTextStyle: .caption1))) 91 | fonts.append(("caption2", preferredFont(forTextStyle: .caption2))) 92 | if #available(iOS 11.0, *) { 93 | fonts.append(("largeTitle", preferredFont(forTextStyle: .largeTitle))) 94 | } 95 | return fonts 96 | } 97 | } 98 | 99 | public extension DynamicTypography where FontStyle == UIFont.TextStyle { 100 | static func namedTypography() -> [NameFonts] { 101 | var fonts: [NameFonts] = [] 102 | fonts.append(("body", preferredFont(forTextStyle: .body))) 103 | fonts.append(("title1", preferredFont(forTextStyle: .title1))) 104 | fonts.append(("title2", preferredFont(forTextStyle: .title2))) 105 | fonts.append(("title3", preferredFont(forTextStyle: .title3))) 106 | fonts.append(("headline", preferredFont(forTextStyle: .headline))) 107 | fonts.append(("subheadline", preferredFont(forTextStyle: .subheadline))) 108 | fonts.append(("callout", preferredFont(forTextStyle: .callout))) 109 | fonts.append(("footnote", preferredFont(forTextStyle: .footnote))) 110 | fonts.append(("caption1", preferredFont(forTextStyle: .caption1))) 111 | fonts.append(("caption2", preferredFont(forTextStyle: .caption2))) 112 | if #available(iOS 11.0, *) { 113 | fonts.append(("largeTitle", preferredFont(forTextStyle: .largeTitle))) 114 | } 115 | return fonts 116 | } 117 | } 118 | 119 | // Debug only 120 | 121 | public typealias NamedColor = (String, UIColor) 122 | 123 | public extension LightenColorSet { 124 | static var namedLightColors: [NamedColor] { 125 | return [("lighten2", lighten2), ("lighten1", lighten1)] 126 | } 127 | } 128 | 129 | public extension DarkenColorSet { 130 | static var namedDarkColors: [NamedColor] { 131 | return [("darken1", darken1), ("darken2", darken2)] 132 | } 133 | } 134 | 135 | // lighter 136 | public extension ExtendedLightenColorSet { 137 | static var namedExdenedLightColors: [NamedColor] { 138 | return [("lighten4", lighten4), ("lighten3", lighten3)] 139 | } 140 | } 141 | 142 | public extension ExtendedDarkenColorSet { 143 | static var namedExdenedDarkColors: [NamedColor] { 144 | return [("darken3", darken3), ("darken4", darken4)] 145 | } 146 | } 147 | 148 | public extension ColorPalette { 149 | static var namedColors: [NamedColor] { 150 | var list: [NamedColor] = [] 151 | list.append(contentsOf: namedLightColors) 152 | list.append(("base", base)) 153 | list.append(contentsOf: namedDarkColors) 154 | return list 155 | } 156 | } 157 | 158 | public extension LargerColorPalette { 159 | static var namedColors: [NamedColor] { 160 | var list: [NamedColor] = [] 161 | list.append(contentsOf: namedExdenedLightColors) 162 | list.append(contentsOf: namedLightColors) 163 | list.append(("base", base)) 164 | list.append(contentsOf: namedDarkColors) 165 | list.append(contentsOf: namedExdenedDarkColors) 166 | return list 167 | } 168 | } 169 | 170 | public extension IconSize { 171 | /// Debug helper methods, to preview items for this collection 172 | /// 173 | /// Only for debuging. 174 | /// - Returns: all items 175 | static func previewItems() -> [(String, IconSize)] { 176 | return [ 177 | ("small", .small), 178 | ("medium", .medium), 179 | ("large", .large), 180 | ] 181 | } 182 | } 183 | 184 | public extension SemanticColorPalette { 185 | /// Debug helper methods, to preview items for this collection 186 | /// 187 | /// Only for debuging. 188 | /// - Returns: all items 189 | static func previewItems() -> [NamedColor] { 190 | var namedColors: [NamedColor] = [] 191 | 192 | let successColors = success.namedColors.map({ (nameColor) -> NamedColor in 193 | ("Success - \(nameColor.0)", nameColor.1) 194 | }) 195 | 196 | let warningColors = warning.namedColors.map({ (nameColor) -> NamedColor in 197 | ("Warning - \(nameColor.0)", nameColor.1) 198 | }) 199 | 200 | let infoColors = info.namedColors.map({ (nameColor) -> NamedColor in 201 | ("Info - \(nameColor.0)", nameColor.1) 202 | }) 203 | 204 | let errorColors = error.namedColors.map({ (nameColor) -> NamedColor in 205 | ("Error - \(nameColor.0)", nameColor.1) 206 | }) 207 | 208 | namedColors.append(contentsOf: successColors) 209 | namedColors.append(contentsOf: warningColors) 210 | namedColors.append(contentsOf: infoColors) 211 | namedColors.append(contentsOf: errorColors) 212 | 213 | return namedColors 214 | } 215 | } 216 | -------------------------------------------------------------------------------- /Source/DesignDebuggerViewController.swift: -------------------------------------------------------------------------------- 1 | // Doric 2 | // 3 | // Copyright (c) 2019 Jay K. 4 | // 5 | // Permission is hereby granted, free of charge, to any person obtaining a copy 6 | // of this software and associated documentation files (the "Software"), to deal 7 | // in the Software without restriction, including without limitation the rights 8 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | // copies of the Software, and to permit persons to whom the Software is 10 | // furnished to do so, subject to the following conditions: 11 | // 12 | // The above copyright notice and this permission notice shall be included in 13 | // all copies or substantial portions of the Software. 14 | // 15 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 21 | // THE SOFTWARE. 22 | 23 | import UIKit 24 | 25 | /// Settings to configure instance of `Doric` 26 | public struct Settings { 27 | /// Spacing between graph rows and columns 28 | public let spacing: CGFloat 29 | 30 | /// Color for graph 31 | let graphColor = UIColor.black 32 | 33 | public init(spacing: LayoutValueRepresentable) { 34 | self.spacing = spacing.rawValue 35 | } 36 | 37 | /// Default settings instance 38 | /// 39 | /// - Returns: returns `Settings` instance with 8.0 point space 40 | static func `default`() -> Settings { 41 | return Settings(spacing: Space.p1) 42 | } 43 | 44 | /// Color for graphView strock 45 | var strockColor: CGColor { 46 | return graphColor.withAlphaComponent(0.6).cgColor 47 | } 48 | } 49 | 50 | /// Internal class to draw graph on top current interface. 51 | class DesignDebuggerViewController: UIViewController { 52 | var closeButton: UIButton! 53 | var graphView: GraphView! 54 | var settings: Settings? 55 | 56 | convenience init(settings: Settings) { 57 | self.init(nibName: nil, bundle: nil) 58 | self.settings = settings 59 | } 60 | 61 | override func viewDidLoad() { 62 | super.viewDidLoad() 63 | 64 | let graphView = GraphView(frame: .zero) 65 | self.graphView = graphView 66 | view.insertSubview(graphView, at: 0) 67 | graphView.backgroundColor = UIColor.clear 68 | graphView.anchorEdges(view) 69 | graphView.options = settings ?? Settings.default() 70 | 71 | closeButton = UIButton() 72 | view.addSubview(closeButton) 73 | closeButton.anchorIcon(.medium) 74 | closeButton.anchorTrailing(view, constant: .equalTo(Space.p2)) 75 | closeButton.anchorBottom(view, constant: .equalTo(Space.p2)) 76 | closeButton.setImage(UIImage.closeImage, for: .normal) 77 | closeButton.addTarget(self, action: #selector(onClose), for: .touchUpInside) 78 | } 79 | 80 | @objc func onClose() { 81 | Doric.shared.isHidden = true 82 | } 83 | } 84 | -------------------------------------------------------------------------------- /Source/Doric.h: -------------------------------------------------------------------------------- 1 | // Doric 2 | // 3 | // Copyright (c) 2019 Jay K. 4 | // 5 | // Permission is hereby granted, free of charge, to any person obtaining a copy 6 | // of this software and associated documentation files (the "Software"), to deal 7 | // in the Software without restriction, including without limitation the rights 8 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | // copies of the Software, and to permit persons to whom the Software is 10 | // furnished to do so, subject to the following conditions: 11 | // 12 | // The above copyright notice and this permission notice shall be included in 13 | // all copies or substantial portions of the Software. 14 | // 15 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 21 | // THE SOFTWARE. 22 | 23 | #import 24 | 25 | //! Project version number for Doric. 26 | FOUNDATION_EXPORT double DoricVersionNumber; 27 | 28 | //! Project version string for Doric. 29 | FOUNDATION_EXPORT const unsigned char DoricVersionString[]; 30 | 31 | // In this header, you should import all the public headers of your framework using statements like #import 32 | 33 | 34 | -------------------------------------------------------------------------------- /Source/Doric.swift: -------------------------------------------------------------------------------- 1 | // Doric 2 | // 3 | // Copyright (c) 2019 Jay K. 4 | // 5 | // Permission is hereby granted, free of charge, to any person obtaining a copy 6 | // of this software and associated documentation files (the "Software"), to deal 7 | // in the Software without restriction, including without limitation the rights 8 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | // copies of the Software, and to permit persons to whom the Software is 10 | // furnished to do so, subject to the following conditions: 11 | // 12 | // The above copyright notice and this permission notice shall be included in 13 | // all copies or substantial portions of the Software. 14 | // 15 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 21 | // THE SOFTWARE. 22 | 23 | import UIKit 24 | 25 | /// Instance to access debug tools i.e. GraphView. 26 | public class Doric: NSObject { 27 | private override init() {} 28 | 29 | /// Shared instance to access various properties and settings for graph debug view. 30 | public static let shared = Doric() 31 | 32 | /** 33 | Settings to configure graph view. 34 | 35 | Create instance of `Settings` and pass to 'Doric' to refect changes for graphView. Will refact only before view presented. 36 | */ 37 | 38 | public var settings: Settings = Settings.default() 39 | 40 | /// Internal window to keep track of touchable area i.e close button. 41 | private class DebugWindow: UIWindow { 42 | // Keep reference of control to allow touch 43 | weak var button: UIButton? 44 | override func point(inside point: CGPoint, with _: UIEvent?) -> Bool { 45 | guard let rect = button?.frame else { return true } 46 | return rect.contains(point) 47 | } 48 | } 49 | 50 | /// Internal window on top of views will be displayed. 51 | private var window: DebugWindow? 52 | 53 | /** 54 | A Boolean value that determines whether the debugger graph view is hidden. 55 | 56 | Setting the value of this property to true hides the graph and setting it to false shows the graph. The default value is false. 57 | */ 58 | public var isHidden: Bool = true { 59 | didSet { 60 | if !isHidden { 61 | showGraphView() 62 | } else { 63 | dismissGraphView() 64 | } 65 | } 66 | } 67 | } 68 | 69 | // MARK: - Support methods 70 | 71 | fileprivate extension Doric { 72 | // Shows debugger window 73 | private func showGraphView() { 74 | if window != nil { 75 | return 76 | } 77 | 78 | let viewController = DesignDebuggerViewController(settings: settings) 79 | viewController.settings = settings 80 | 81 | window = DebugWindow(frame: UIScreen.main.bounds) 82 | window?.windowLevel = UIWindow.Level.statusBar + 1 83 | window?.rootViewController = viewController 84 | window?.makeKeyAndVisible() 85 | window?.button = viewController.closeButton 86 | } 87 | 88 | // Hides debugger window 89 | private func dismissGraphView() { 90 | guard window != nil else { 91 | return 92 | } 93 | 94 | window?.button = nil 95 | window?.resignKey() 96 | window?.rootViewController = nil 97 | window = nil 98 | } 99 | } 100 | -------------------------------------------------------------------------------- /Source/GradientColor.swift: -------------------------------------------------------------------------------- 1 | // Doric 2 | // 3 | // Copyright (c) 2019 Jay K. 4 | // 5 | // Permission is hereby granted, free of charge, to any person obtaining a copy 6 | // of this software and associated documentation files (the "Software"), to deal 7 | // in the Software without restriction, including without limitation the rights 8 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | // copies of the Software, and to permit persons to whom the Software is 10 | // furnished to do so, subject to the following conditions: 11 | // 12 | // The above copyright notice and this permission notice shall be included in 13 | // all copies or substantial portions of the Software. 14 | // 15 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 21 | // THE SOFTWARE. 22 | 23 | import UIKit 24 | 25 | /** 26 | 27 | `GradientColor` protocol provides gradient defination with start & end colors and start & end points. Helper to create gradient using `CAGradientLayer`. 28 | 29 | ``` 30 | // Left-to-Right gradient color can be defined as below 31 | struct CardGradientColor: GradientColor { 32 | let startColor = UIColor("#1e3c72") 33 | let endColor = UIColor("#2a5298") 34 | } 35 | 36 | // Single color with darker/light shade gradient color can be defined as below. 37 | //`endColor` will be darker or ligher of `startColor` 38 | struct ShadedGradientColor: GradientColor { 39 | let startColor = UIColor("#1e3c72") 40 | } 41 | ``` 42 | 43 | `UIColor` also implements `GradientColor` protocol, so instance of UIColor can be used directly wherever `GradientColor` used. 44 | 45 | - SeeAlso:- `GradientView` 46 | - SeeAlso:- `public convenience init(gradient: GradientColor) 47 | 48 | */ 49 | 50 | public protocol GradientColor { 51 | /// Start color of gradient 52 | var startColor: UIColor { get } 53 | 54 | /// End color of gradient, by default 0.5 ligher or darker of `startColor` 55 | var endColor: UIColor { get } 56 | 57 | /// Start point for gradient 58 | var startPoint: CGPoint { get } 59 | 60 | /// End point for gradient 61 | var endPoint: CGPoint { get } 62 | } 63 | 64 | /// Default implementions for `GradientColor` 65 | public extension GradientColor { 66 | /// Provides list of `CGColor` to create gradient using `CAGradientLayer` 67 | var colors: [CGColor] { 68 | return [startColor.cgColor, endColor.cgColor] 69 | } 70 | 71 | /// Default start point for gradient is (0.0, 0.5) 72 | var startPoint: CGPoint { 73 | return CGPoint(x: 0.0, y: 0.5) 74 | } 75 | 76 | /// Default end point for gradient is (1.0, 0.5) 77 | var endPoint: CGPoint { 78 | return CGPoint(x: 1.0, y: 0.5) 79 | } 80 | 81 | /// End color of gradient, by default 0.5 ligher or darker of `startColor` 82 | var endColor: UIColor { 83 | if startColor.whiteComponent > 0.5 { 84 | return startColor.darker(by: 0.50) 85 | } else { 86 | return startColor.lighter(by: 0.50) 87 | } 88 | } 89 | } 90 | 91 | // MARK: - UIColor implements GradientColor 92 | 93 | extension UIColor: GradientColor { 94 | /// Implements `GradientColor` protocol, by default current color is startColor for gradient defination 95 | public var startColor: UIColor { 96 | return self 97 | } 98 | } 99 | -------------------------------------------------------------------------------- /Source/GradientView.swift: -------------------------------------------------------------------------------- 1 | // Doric 2 | // 3 | // Copyright (c) 2019 Jay K. 4 | // 5 | // Permission is hereby granted, free of charge, to any person obtaining a copy 6 | // of this software and associated documentation files (the "Software"), to deal 7 | // in the Software without restriction, including without limitation the rights 8 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | // copies of the Software, and to permit persons to whom the Software is 10 | // furnished to do so, subject to the following conditions: 11 | // 12 | // The above copyright notice and this permission notice shall be included in 13 | // all copies or substantial portions of the Software. 14 | // 15 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 21 | // THE SOFTWARE. 22 | 23 | import UIKit 24 | 25 | /// Creates gradient view 26 | open class GradientView: UIView { 27 | var gradientLayer: CAGradientLayer! 28 | 29 | /// Start point of gradient, by default (0.0, 0.5). 30 | open var startPoint: CGPoint = CGPoint(x: 0.0, y: 0.5) { 31 | didSet { 32 | setNeedsLayout() 33 | } 34 | } 35 | 36 | /// End point of gradient, by default (0.0, 0.5). 37 | open var endPoint: CGPoint = CGPoint(x: 1.0, y: 0.5) { 38 | didSet { 39 | setNeedsLayout() 40 | } 41 | } 42 | 43 | /// Start color of gradient. 44 | open var startColor: UIColor = .black { 45 | didSet { 46 | setNeedsLayout() 47 | } 48 | } 49 | 50 | /// End color of gradient. 51 | open var endColor: UIColor = .white { 52 | didSet { 53 | setNeedsLayout() 54 | } 55 | } 56 | 57 | open override class var layerClass: AnyClass { 58 | return CAGradientLayer.self 59 | } 60 | 61 | open override func layoutSubviews() { 62 | gradientLayer = layer as? CAGradientLayer 63 | gradientLayer.colors = [startColor.cgColor, endColor.cgColor] 64 | gradientLayer.startPoint = startPoint 65 | gradientLayer.endPoint = endPoint 66 | } 67 | } 68 | 69 | // MARK: - Extention to create gradient with colors 70 | 71 | public extension GradientView { 72 | /// Convenience initializer to create an instance of `GradientView` using `GradientColor` 73 | /// 74 | /// - Parameter gradient: GradientColor defination, see `GradientColor` 75 | /// - SeeAlso:- `GradientColor` 76 | convenience init(gradient: GradientColor) { 77 | self.init(frame: .zero) 78 | startColor = gradient.startColor 79 | endColor = gradient.endColor 80 | startPoint = gradient.startPoint 81 | endPoint = gradient.endPoint 82 | } 83 | } 84 | -------------------------------------------------------------------------------- /Source/GraphView.swift: -------------------------------------------------------------------------------- 1 | // Doric 2 | // 3 | // Copyright (c) 2019 Jay K. 4 | // 5 | // Permission is hereby granted, free of charge, to any person obtaining a copy 6 | // of this software and associated documentation files (the "Software"), to deal 7 | // in the Software without restriction, including without limitation the rights 8 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | // copies of the Software, and to permit persons to whom the Software is 10 | // furnished to do so, subject to the following conditions: 11 | // 12 | // The above copyright notice and this permission notice shall be included in 13 | // all copies or substantial portions of the Software. 14 | // 15 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 21 | // THE SOFTWARE. 22 | 23 | import UIKit 24 | 25 | private extension UIScreen { 26 | /// One pixel as per scale. 27 | var pixel: CGFloat { 28 | return 1.0 / scale 29 | } 30 | } 31 | 32 | /// View to draw graph 33 | class GraphView: UIView { 34 | var options = Settings.default() { 35 | didSet { 36 | setNeedsDisplay() 37 | } 38 | } 39 | 40 | private let lineWidth = UIScreen.main.pixel 41 | 42 | override func draw(_: CGRect) { 43 | guard let context = UIGraphicsGetCurrentContext() else { 44 | return 45 | } 46 | 47 | let spacing: CGFloat = options.spacing 48 | let columns: CGFloat = bounds.width / spacing 49 | let rows: CGFloat = bounds.height / spacing 50 | 51 | context.setLineWidth(lineWidth) 52 | context.setStrokeColor(options.strockColor) 53 | context.setShouldAntialias(false) 54 | 55 | for var colIndex in 0 ..< Int(columns) + 1 { 56 | let startPoint = CGPoint(x: spacing * CGFloat(colIndex), y: 0.0) 57 | let endPoint = CGPoint(x: startPoint.x, y: frame.size.height) 58 | context.move(to: CGPoint(x: startPoint.x, y: startPoint.y)) 59 | context.addLine(to: CGPoint(x: endPoint.x, y: endPoint.y)) 60 | context.strokePath() 61 | colIndex += 1 62 | } 63 | 64 | for var rowIndex in 0 ..< Int(rows) + 1 { 65 | let startPoint = CGPoint(x: 0.0, y: spacing * CGFloat(rowIndex)) 66 | let endPoint = CGPoint(x: frame.size.width, y: startPoint.y) 67 | context.move(to: CGPoint(x: startPoint.x, y: startPoint.y)) 68 | context.addLine(to: CGPoint(x: endPoint.x, y: endPoint.y)) 69 | context.strokePath() 70 | rowIndex += 1 71 | } 72 | } 73 | 74 | override func layoutSubviews() { 75 | super.layoutSubviews() 76 | setNeedsDisplay() 77 | } 78 | } 79 | -------------------------------------------------------------------------------- /Source/Iconography.swift: -------------------------------------------------------------------------------- 1 | // Doric 2 | // 3 | // Copyright (c) 2019 Jay K. 4 | // 5 | // Permission is hereby granted, free of charge, to any person obtaining a copy 6 | // of this software and associated documentation files (the "Software"), to deal 7 | // in the Software without restriction, including without limitation the rights 8 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | // copies of the Software, and to permit persons to whom the Software is 10 | // furnished to do so, subject to the following conditions: 11 | // 12 | // The above copyright notice and this permission notice shall be included in 13 | // all copies or substantial portions of the Software. 14 | // 15 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 21 | // THE SOFTWARE. 22 | 23 | import UIKit 24 | 25 | public extension UIImageView { 26 | /// set image with tint color. 27 | func tintedImageWith(color: UIColor) { 28 | image = image?.withRenderingMode(.alwaysTemplate) 29 | tintColor = color 30 | } 31 | } 32 | 33 | public extension UIImage { 34 | /// Create template image. 35 | /// 36 | /// - Parameters: 37 | /// - named: name of image. 38 | /// - bundle: bundle which contains image. 39 | /// - Returns: a template image. 40 | static func template(named: String, bundle: Bundle = Bundle.main) -> UIImage? { 41 | return UIImage(named: named, in: bundle, compatibleWith: nil)?.withRenderingMode(.alwaysTemplate) 42 | } 43 | 44 | /// Create template image with color. 45 | /// 46 | /// - Parameters: 47 | /// - named: name of image. 48 | /// - bundle: bundle which contains image. 49 | /// - tintColor: tintColor 50 | /// - Returns: a template image. 51 | static func template(named: String, bundle: Bundle = Bundle.main, tintColor: UIColor) -> UIImage? { 52 | return template(named: named, bundle: bundle)?.tint(with: tintColor) 53 | } 54 | 55 | private func tint(with color: UIColor) -> UIImage? { 56 | UIGraphicsBeginImageContextWithOptions(size, false, scale) 57 | color.set() 58 | draw(in: CGRect(origin: .zero, size: size)) 59 | guard let tintedImage = UIGraphicsGetImageFromCurrentImageContext() else { 60 | return nil 61 | } 62 | UIGraphicsEndImageContext() 63 | return tintedImage 64 | } 65 | } 66 | 67 | extension UIImage { 68 | static var closeImage: UIImage? { 69 | guard let bundle = Bundle.moduleBundle else { 70 | return nil 71 | } 72 | return UIImage.template(named: "internal-icon-close", bundle: bundle)?.tint(with: UIColor.black) 73 | } 74 | } 75 | -------------------------------------------------------------------------------- /Source/Implemented.swift: -------------------------------------------------------------------------------- 1 | // Doric 2 | // 3 | // Copyright (c) 2019 Jay K. 4 | // 5 | // Permission is hereby granted, free of charge, to any person obtaining a copy 6 | // of this software and associated documentation files (the "Software"), to deal 7 | // in the Software without restriction, including without limitation the rights 8 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | // copies of the Software, and to permit persons to whom the Software is 10 | // furnished to do so, subject to the following conditions: 11 | // 12 | // The above copyright notice and this permission notice shall be included in 13 | // all copies or substantial portions of the Software. 14 | // 15 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 21 | // THE SOFTWARE. 22 | 23 | import UIKit 24 | 25 | /// DualThemeManager 26 | open class DualThemeManager: NSObject, DualThemeSwitcher { 27 | /// Main theme. 28 | public let mainTheme: Theme 29 | 30 | /// Secondary theme. 31 | public let seconadaryTheme: Theme 32 | 33 | /// Theme event notifier. 34 | public let notifier: ThemeListener 35 | 36 | /// Current theme. 37 | open var theme: Theme 38 | 39 | public init(mainTheme: Theme, alternateTheme: Theme) { 40 | self.mainTheme = mainTheme 41 | seconadaryTheme = alternateTheme 42 | theme = mainTheme 43 | notifier = ThemeNotificationCenterNotifier() 44 | } 45 | } 46 | 47 | /// DefaultGrayScalePalette 48 | public struct DefaultGrayScalePalette: LargerColorPalette { 49 | public static let lighten1 = UIColor("#999999") 50 | public static let lighten2 = UIColor("#b2b2b2") 51 | public static let lighten3 = UIColor("#cccccc") 52 | public static let lighten4 = UIColor("#e5e5e5") 53 | public static let base = UIColor("#7f7f7f") 54 | public static let darken1 = UIColor("#666666") 55 | public static let darken2 = UIColor("#4c4c4c") 56 | public static let darken3 = UIColor("#323232") 57 | public static let darken4 = UIColor("#191919") 58 | } 59 | 60 | // MARK: - System colors 61 | 62 | public extension UIColor { 63 | /// System colors 64 | struct System { 65 | /// system red 66 | public static let red = UIColor("#FF3B30") 67 | 68 | /// system orange 69 | public static let orange = UIColor("#FF9500") 70 | 71 | /// system yellow 72 | public static let yellow = UIColor("#FFCC00") 73 | 74 | /// system green 75 | public static let green = UIColor("#4CD964") 76 | 77 | /// system teal 78 | public static let teal = UIColor("#5AC8FA") 79 | 80 | /// system blue 81 | public static let blue = UIColor("#007AFF") 82 | 83 | /// system purple 84 | public static let purple = UIColor("#5856D6") 85 | 86 | /// system pink 87 | public static let pink = UIColor("#FF2D55") 88 | 89 | /// system white 90 | public static let whiteColor = UIColor("#FFFFFF") 91 | 92 | /// system extra light gray 93 | public static let extraLightGrayColor = UIColor("#EFEFF4") 94 | 95 | /// system light gray 96 | public static let lightGrayColor = UIColor("#E5E5EA") 97 | 98 | /// system light mid gray 99 | public static let lightMidGrayColor = UIColor("#D1D1D6") 100 | 101 | /// system mid gray 102 | public static let midGrayColor = UIColor("#C7C7CC") 103 | 104 | /// system gray 105 | public static let grayColor = UIColor("#8E8E93") 106 | 107 | /// system black 108 | public static let blackColor = UIColor("#000000") 109 | } 110 | } 111 | 112 | /// DefaultSemanticColorPalette 113 | public struct DefaultSemanticColorPalette: SemanticColorPalette { 114 | public static let error: ColorPalette.Type = ErrorColor.self 115 | public static let warning: ColorPalette.Type = WarningColor.self 116 | public static let success: ColorPalette.Type = SuccessColor.self 117 | public static let info: ColorPalette.Type = InformationColor.self 118 | 119 | private struct ErrorColor: ColorPalette { 120 | static let base: UIColor = UIColor("#BB0000") 121 | } 122 | 123 | private struct WarningColor: ColorPalette { 124 | static let base: UIColor = UIColor("#E78C07") 125 | } 126 | 127 | private struct SuccessColor: ColorPalette { 128 | static let base: UIColor = UIColor("#2B7D2B") 129 | } 130 | 131 | private struct InformationColor: ColorPalette { 132 | static let base: UIColor = UIColor("#5E696E") 133 | } 134 | } 135 | 136 | /// SystemTypography - System font set 137 | public struct SystemTypography: DynamicTypography { 138 | public typealias FontStyle = UIFont.TextStyle 139 | 140 | private static let fonts: [UIFont.TextStyle: UIFont] = 141 | [UIFont.TextStyle.caption2: UIFont.systemFont(ofSize: 9.0), 142 | UIFont.TextStyle.caption1: UIFont.systemFont(ofSize: 12.0), 143 | UIFont.TextStyle.footnote: UIFont.systemFont(ofSize: 13.0), 144 | UIFont.TextStyle.subheadline: UIFont.systemFont(ofSize: 15.0), 145 | UIFont.TextStyle.callout: UIFont.systemFont(ofSize: 16.0), 146 | UIFont.TextStyle.body: UIFont.systemFont(ofSize: 17.0), 147 | UIFont.TextStyle.headline: UIFont.boldSystemFont(ofSize: 15.0), 148 | UIFont.TextStyle.title3: UIFont.systemFont(ofSize: 20.0), 149 | UIFont.TextStyle.title2: UIFont.systemFont(ofSize: 22.0), 150 | UIFont.TextStyle.title1: UIFont.systemFont(ofSize: 28.0), 151 | UIFont.TextStyle.largeTitle: UIFont.systemFont(ofSize: 34.0)] 152 | 153 | public static func font(forTextStyle style: UIFont.TextStyle) -> UIFont { 154 | return fonts[style] ?? UIFont.default 155 | } 156 | 157 | public static func preferredFont(forTextStyle style: FontStyle) -> UIFont { 158 | return UIFont.preferredFont(forTextStyle: style) 159 | } 160 | } 161 | -------------------------------------------------------------------------------- /Source/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | $(DEVELOPMENT_LANGUAGE) 7 | CFBundleExecutable 8 | $(EXECUTABLE_NAME) 9 | CFBundleIdentifier 10 | $(PRODUCT_BUNDLE_IDENTIFIER) 11 | CFBundleInfoDictionaryVersion 12 | 6.0 13 | CFBundleName 14 | $(PRODUCT_NAME) 15 | CFBundlePackageType 16 | FMWK 17 | CFBundleShortVersionString 18 | 1.0 19 | CFBundleVersion 20 | $(CURRENT_PROJECT_VERSION) 21 | 22 | 23 | -------------------------------------------------------------------------------- /Source/Layout.swift: -------------------------------------------------------------------------------- 1 | // Doric 2 | // 3 | // Copyright (c) 2019 Jay K. 4 | // 5 | // Permission is hereby granted, free of charge, to any person obtaining a copy 6 | // of this software and associated documentation files (the "Software"), to deal 7 | // in the Software without restriction, including without limitation the rights 8 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | // copies of the Software, and to permit persons to whom the Software is 10 | // furnished to do so, subject to the following conditions: 11 | // 12 | // The above copyright notice and this permission notice shall be included in 13 | // all copies or substantial portions of the Software. 14 | // 15 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 21 | // THE SOFTWARE. 22 | 23 | import UIKit 24 | 25 | // MARK: - 26 | 27 | /// Type which can reprent value, Mostly used with autolayouts, but not limited to it. Contains some utility methods to create margins, insets etc. 28 | public protocol LayoutValueRepresentable { 29 | /// Raw value 30 | var rawValue: CGFloat { get } 31 | } 32 | 33 | public extension LayoutValueRepresentable { 34 | /// One pixel value based on device scale 35 | static var pixel: CGFloat { 36 | return 1.0 / UIScreen.main.scale 37 | } 38 | } 39 | 40 | public extension LayoutValueRepresentable { 41 | /// multiply value with rawValue. 42 | func by(_ multiplier: CGFloat) -> CGFloat { 43 | return rawValue * multiplier 44 | } 45 | 46 | /// edgeInsets with values. 47 | func edgeInsets() -> UIEdgeInsets { 48 | return UIEdgeInsets(top: rawValue, left: rawValue, bottom: rawValue, right: rawValue) 49 | } 50 | 51 | /// create horizontal rect with rawValue. 52 | func hRect(_ value: Self) -> UIEdgeInsets { 53 | return UIEdgeInsets(top: rawValue, left: value.rawValue, bottom: rawValue, right: value.rawValue) 54 | } 55 | 56 | /// create vertical rect with rawValue. 57 | func vRect(_ value: Self) -> UIEdgeInsets { 58 | return UIEdgeInsets(top: value.rawValue, left: rawValue, bottom: value.rawValue, right: rawValue) 59 | } 60 | } 61 | 62 | // swiftlint:disable all 63 | 64 | /// Space - represents default set of space sizes. 65 | /// 66 | /// - p0: Space value 0.0 67 | /// - p1: Space value 8.0 68 | /// - p2: Space value 16.0 69 | /// - p3: Space value 24.0 70 | /// - p4: Space value 32.0 71 | /// - p5: Space value 40.0 72 | /// - p6: Space value 48.0 73 | /// - p7: Space value 56.0 74 | /// - p8: Space value 64.0 75 | public enum Space: CGFloat, LayoutValueRepresentable { 76 | /// p0 77 | case p0 = 0.0 78 | 79 | /// p1 80 | case p1 = 8.0 81 | 82 | /// p2 83 | case p2 = 16.0 84 | 85 | /// p3 86 | case p3 = 24.0 87 | 88 | /// p4 89 | case p4 = 32.0 90 | 91 | /// p5 92 | case p5 = 40.0 93 | 94 | /// p6 95 | case p6 = 48.0 96 | 97 | /// p7 98 | case p7 = 56.0 99 | 100 | /// p8 101 | case p8 = 64.0 102 | } 103 | 104 | // swiftlint:enable all 105 | -------------------------------------------------------------------------------- /Source/Notification.swift: -------------------------------------------------------------------------------- 1 | // Doric 2 | // 3 | // Copyright (c) 2019 Jay K. 4 | // 5 | // Permission is hereby granted, free of charge, to any person obtaining a copy 6 | // of this software and associated documentation files (the "Software"), to deal 7 | // in the Software without restriction, including without limitation the rights 8 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | // copies of the Software, and to permit persons to whom the Software is 10 | // furnished to do so, subject to the following conditions: 11 | // 12 | // The above copyright notice and this permission notice shall be included in 13 | // all copies or substantial portions of the Software. 14 | // 15 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 21 | // THE SOFTWARE. 22 | 23 | import Foundation 24 | import UIKit 25 | 26 | /// ThemeNotification 27 | public struct ThemeNotification { 28 | public static let didChange = Notification.Name(rawValue: "com.doric.notification.theme.didchange") 29 | } 30 | 31 | extension Notification { 32 | /// Instance of `Theme` 33 | public var theme: Theme? { 34 | return userInfo?[String.themeKey] as? Theme 35 | } 36 | 37 | /// Create `Notification` using `Theme` 38 | /// 39 | /// - Parameters: 40 | /// - name: Notification Name 41 | /// - theme: Theme instance 42 | init(name: Notification.Name, theme: Theme) { 43 | self.init(name: name, object: nil, userInfo: [String.themeKey: theme]) 44 | } 45 | } 46 | 47 | extension NotificationCenter { 48 | /// Posts notification. 49 | /// 50 | /// - Parameters: 51 | /// - name: Notification Name 52 | /// - theme: Theme instance 53 | func postNotification(named name: Notification.Name, with theme: Theme) { 54 | post(Notification(name: name, theme: theme)) 55 | } 56 | } 57 | 58 | fileprivate extension String { 59 | /// Key for theme reference in notification instance. 60 | static let themeKey = "com.doric.theme.key" 61 | } 62 | 63 | /// Listens events for theme 64 | public protocol ThemeListener { 65 | /// Notify theme change. 66 | func notifyChange(_ theme: Theme) 67 | } 68 | 69 | /// Default implemention of `ThemeListener` which posts notifications using `default` notification center. 70 | final class ThemeNotificationCenterNotifier: ThemeListener { 71 | /// Notifies theme change 72 | /// 73 | /// - Parameter theme: Theme instance 74 | public func notifyChange(_ theme: Theme) { 75 | NotificationCenter.default.postNotification(named: ThemeNotification.didChange, with: theme) 76 | } 77 | } 78 | -------------------------------------------------------------------------------- /Source/Scale.swift: -------------------------------------------------------------------------------- 1 | // Doric 2 | // 3 | // Copyright (c) 2019 Jay K. 4 | // 5 | // Permission is hereby granted, free of charge, to any person obtaining a copy 6 | // of this software and associated documentation files (the "Software"), to deal 7 | // in the Software without restriction, including without limitation the rights 8 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | // copies of the Software, and to permit persons to whom the Software is 10 | // furnished to do so, subject to the following conditions: 11 | // 12 | // The above copyright notice and this permission notice shall be included in 13 | // all copies or substantial portions of the Software. 14 | // 15 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 21 | // THE SOFTWARE. 22 | 23 | import UIKit 24 | 25 | /// Scale represents small set of scale sizes. 26 | public protocol Scale { 27 | /// small. 28 | static var small: CGFloat { get } 29 | 30 | /// medium. 31 | static var medium: CGFloat { get } 32 | 33 | /// large. 34 | static var large: CGFloat { get } 35 | } 36 | 37 | /// FullScale represents small set of scale sizes. 38 | public protocol FullScale: Scale { 39 | /// extraSmall. 40 | static var extraSmall: CGFloat { get } 41 | 42 | /// extraLarge. 43 | static var extraLarge: CGFloat { get } 44 | 45 | /// extraExtraLarge. 46 | static var extraExtraLarge: CGFloat { get } 47 | 48 | /// extraExtraExtraLarge. 49 | static var extraExtraExtraLarge: CGFloat { get } 50 | } 51 | 52 | /// ValueLevel represents set of level for a value. 53 | public protocol ValueLevel { 54 | /// high 55 | static var high: CGFloat { get } 56 | 57 | /// medium 58 | static var medium: CGFloat { get } 59 | 60 | /// low 61 | static var low: CGFloat { get } 62 | } 63 | 64 | /// TwoStateValueLevel represents two state for a value. 65 | public protocol TwoStateValueLevel { 66 | /// full 67 | static var full: CGFloat { get } 68 | 69 | /// none 70 | static var none: CGFloat { get } 71 | } 72 | 73 | /// Default Scale values. 74 | public extension Scale { 75 | static var small: CGFloat { return 12.0 } 76 | static var medium: CGFloat { return 14.0 } 77 | static var large: CGFloat { return 18.0 } 78 | } 79 | 80 | /// Default FullScale values. 81 | public extension FullScale { 82 | static var extraSmall: CGFloat { return 8.0 } 83 | static var extraLarge: CGFloat { return 36.0 } 84 | static var extraExtraLarge: CGFloat { return 48.0 } 85 | static var extraExtraExtraLarge: CGFloat { return 60.0 } 86 | } 87 | 88 | /// Default Fullscale availble with default values. 89 | public struct SizeScale: FullScale {} 90 | 91 | /// TransparencyLevel represents level of transparency. 92 | public protocol TransparencyLevel: ValueLevel, TwoStateValueLevel {} 93 | 94 | public struct Transparency: TransparencyLevel { 95 | /// high value, default 0.25 96 | public static let high: CGFloat = 0.25 97 | 98 | /// medium value, default 0.50 99 | public static let medium: CGFloat = 0.50 100 | 101 | /// low value, default 0.75 102 | public static let low: CGFloat = 0.75 103 | 104 | /// full value, default 0.0 105 | public static let full: CGFloat = 0.0 106 | 107 | /// none value, default 1.0 108 | public static let none: CGFloat = 1.0 109 | } 110 | 111 | /// CornerRadius represents corder radius scales. 112 | public struct CornerRadius: Scale { 113 | /// small, default 2.0. 114 | public static let small: CGFloat = 2.0 115 | 116 | /// medium, default 4.0. 117 | public static let medium: CGFloat = 4.0 118 | 119 | /// large, default 8.0. 120 | public static let large: CGFloat = 8.0 121 | } 122 | 123 | /// Border represents border scales. 124 | public struct Border: FullScale { 125 | /// small, default 0.5. 126 | public static let extraSmall: CGFloat = 0.5 127 | 128 | /// small, default 1.0. 129 | public static let small: CGFloat = 1.0 130 | 131 | /// small, default 2.0. 132 | public static let medium: CGFloat = 2.0 133 | 134 | /// small, default 3.0. 135 | public static let large: CGFloat = 3.0 136 | 137 | /// small, default 4.0. 138 | public static let extraLarge: CGFloat = 4.0 139 | 140 | /// small, default 6.0. 141 | public static let extraExtraLarge: CGFloat = 6.0 142 | 143 | /// small, default 8.0. 144 | public static let extraExtraExtraLarge: CGFloat = 8.0 145 | } 146 | 147 | /// IconSize 148 | /// 149 | /// - small: small size icon 150 | /// - medium: medium size icon 151 | /// - large: large size icon 152 | public enum IconSize: CGFloat, LayoutValueRepresentable { 153 | /// Small icon size, default 24.0 154 | case small = 24.0 155 | 156 | /// Medium icon size, default 36.0 157 | case medium = 36.0 158 | 159 | /// Large icon size, default 48.0 160 | case large = 48.0 161 | } 162 | 163 | public extension IconSize { 164 | /// As CGSize representation 165 | var cgSize: CGSize { 166 | return CGSize(width: rawValue, height: rawValue) 167 | } 168 | } 169 | 170 | /// ButtonHeight 171 | /// 172 | /// - small: small size 173 | /// - medium: medium size 174 | /// - large: large size 175 | public enum ButtonHeight: CGFloat, LayoutValueRepresentable { 176 | /// Small button size 177 | case small = 24.0 178 | 179 | /// Medium button size 180 | case medium = 40.0 181 | 182 | /// Large button size 183 | case large = 48.0 184 | } 185 | 186 | /// Shadow 187 | /// 188 | /// - tiny: tiny shadow 189 | /// - small: small shadow 190 | /// - medium: medium shadow 191 | /// - large: large shadow 192 | public enum Shadow { 193 | /// Tiny 194 | case tiny 195 | 196 | /// Small 197 | case small 198 | 199 | /// Medium 200 | case medium 201 | 202 | /// Large 203 | case large 204 | } 205 | 206 | /// Type alias for VoiceToneLevel 207 | public typealias VoiceToneLevel = ValueLevel 208 | 209 | /// Type alias for BorderSize 210 | public typealias BorderSize = Scale.Type 211 | 212 | /// Type alias for VoiceToneLevel 213 | public typealias CornerRadiusSize = Scale.Type 214 | -------------------------------------------------------------------------------- /Source/Style.swift: -------------------------------------------------------------------------------- 1 | // Doric 2 | // 3 | // Copyright (c) 2019 Jay K. 4 | // 5 | // Permission is hereby granted, free of charge, to any person obtaining a copy 6 | // of this software and associated documentation files (the "Software"), to deal 7 | // in the Software without restriction, including without limitation the rights 8 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | // copies of the Software, and to permit persons to whom the Software is 10 | // furnished to do so, subject to the following conditions: 11 | // 12 | // The above copyright notice and this permission notice shall be included in 13 | // all copies or substantial portions of the Software. 14 | // 15 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 21 | // THE SOFTWARE. 22 | 23 | import UIKit 24 | 25 | /// Style protocol represents style which can be applied on control 26 | public protocol Style { 27 | associatedtype TargetControl 28 | 29 | /// Apple style on control. 30 | /// 31 | /// - Parameter control: control which can be styled. 32 | func performStyle(on control: TargetControl) 33 | } 34 | -------------------------------------------------------------------------------- /Source/Theme.swift: -------------------------------------------------------------------------------- 1 | // Doric 2 | // 3 | // Copyright (c) 2019 Jay K. 4 | // 5 | // Permission is hereby granted, free of charge, to any person obtaining a copy 6 | // of this software and associated documentation files (the "Software"), to deal 7 | // in the Software without restriction, including without limitation the rights 8 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | // copies of the Software, and to permit persons to whom the Software is 10 | // furnished to do so, subject to the following conditions: 11 | // 12 | // The above copyright notice and this permission notice shall be included in 13 | // all copies or substantial portions of the Software. 14 | // 15 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 21 | // THE SOFTWARE. 22 | 23 | import UIKit 24 | 25 | /// Represents them with color palette. Currenly supports only color palettes. 26 | public protocol Theme { 27 | /// identifier for theme. 28 | var identifier: String { get } 29 | 30 | /// colorPalette represented by theme instance. 31 | var colorPalette: MainColorPalette.Type { get } 32 | } 33 | 34 | /// ThemeManager 35 | public protocol ThemeManager { 36 | /// `Theme` instance. 37 | var theme: Theme { get } 38 | } 39 | 40 | /// ThemeSwitcher hods replaceable theme 41 | public protocol ThemeSwitcher: ThemeManager { 42 | /// `Theme` instance. 43 | var theme: Theme { get set } 44 | 45 | /// `ThemeListener` notifies theme evnts/ 46 | var notifier: ThemeListener { get } 47 | } 48 | 49 | /// DualThemeSwitcher holds two instance for theme, helper to create dual themes i.e light/dark mode or day/night mode. 50 | public protocol DualThemeSwitcher: ThemeSwitcher { 51 | /// Main `Theme` instance. 52 | var mainTheme: Theme { get } 53 | 54 | /// Alternate `Theme` instance. 55 | var seconadaryTheme: Theme { get } 56 | } 57 | 58 | // MARK: - ThemeSwitcher 59 | 60 | extension ThemeSwitcher { 61 | /// Set new theme. 62 | /// 63 | /// - Parameter newTheme: newTheme `Theme` instance. 64 | public mutating func setTheme(_ newTheme: Theme) { 65 | guard theme.identifier != newTheme.identifier else { 66 | return 67 | } 68 | theme = newTheme 69 | notifier.notifyChange(theme) 70 | } 71 | } 72 | 73 | // MARK: - DualThemeSwitcher 74 | 75 | extension DualThemeSwitcher { 76 | /// toggle current theme, replace current theme with alternate theme. 77 | public mutating func toggleTheme() { 78 | if theme.identifier == mainTheme.identifier { 79 | setTheme(seconadaryTheme) 80 | } else { 81 | setTheme(mainTheme) 82 | } 83 | } 84 | } 85 | -------------------------------------------------------------------------------- /Source/Typography.swift: -------------------------------------------------------------------------------- 1 | // Doric 2 | // 3 | // Copyright (c) 2019 Jay K. 4 | // 5 | // Permission is hereby granted, free of charge, to any person obtaining a copy 6 | // of this software and associated documentation files (the "Software"), to deal 7 | // in the Software without restriction, including without limitation the rights 8 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | // copies of the Software, and to permit persons to whom the Software is 10 | // furnished to do so, subject to the following conditions: 11 | // 12 | // The above copyright notice and this permission notice shall be included in 13 | // all copies or substantial portions of the Software. 14 | // 15 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 21 | // THE SOFTWARE. 22 | 23 | import UIKit 24 | 25 | public extension UIFont { 26 | /// Fallback fonts wherever font operations failed to provide requested fonts. 27 | class var `default`: UIFont { 28 | return UIFont.systemFont(ofSize: 17.0) 29 | } 30 | } 31 | 32 | /// TypographyOptions options to configure typography 33 | public protocol TypographyOptions { 34 | /// Adjust fonts as per content size category. 35 | static var shouldScaleFont: Bool { get } 36 | } 37 | 38 | public extension TypographyOptions { 39 | /// Default scales fonts. 40 | static var shouldScaleFont: Bool { 41 | return true 42 | } 43 | } 44 | 45 | /// Typography provides static size fonts as per `FontStyle` 46 | public protocol Typography { 47 | associatedtype FontStyle 48 | 49 | /// Returns an instance of the font for the specified `FontStyle` and with font size. 50 | /// 51 | /// - Parameter style: FontStyle 52 | /// - Returns: Created font. 53 | static func font(forTextStyle style: FontStyle) -> UIFont 54 | } 55 | 56 | /// DynamicTypography provides dynamic types fonts along with static size fonts 57 | public protocol DynamicTypography: Typography, TypographyOptions { 58 | /// Returns an instance of the font for the specified `FontStyle` and scaled appropriately for the user's selected content size category. 59 | /// 60 | /// - Parameter style: FontStyle 61 | /// - Returns: Created font. 62 | static func preferredFont(forTextStyle style: FontStyle) -> UIFont 63 | } 64 | 65 | /// FontDescription which can describe font, useful to create fonts represented by external model. 66 | public struct FontDescription { 67 | /// Font name. 68 | public let name: String 69 | 70 | /// Font size. 71 | public let size: CGFloat 72 | 73 | public init(name: String, size: CGFloat) { 74 | self.name = name 75 | self.size = size 76 | } 77 | } 78 | 79 | /// A type with a customized font representation 80 | public protocol FontConvertible { 81 | var font: UIFont? { get } 82 | } 83 | 84 | extension FontDescription: FontConvertible { 85 | public var font: UIFont? { 86 | return UIFont(name: name, size: size) 87 | } 88 | } 89 | 90 | /// Represnts font set. 91 | public protocol Font { 92 | associatedtype TextStyle: Hashable 93 | 94 | /// List of fonts and their text style 95 | var fonts: [TextStyle: FontConvertible] { get } 96 | 97 | /// Creates font for text style 98 | func font(forTextStyle textStyle: TextStyle) -> UIFont 99 | } 100 | 101 | public extension Font { 102 | /// Creates font for text style 103 | func font(forTextStyle textStyle: TextStyle) -> UIFont { 104 | guard let font = fonts[textStyle]?.font else { 105 | return UIFont.default 106 | } 107 | return font 108 | } 109 | } 110 | 111 | /// SystemFont font which represents built in Font Style - `UIFont.TextStyle`. 112 | public protocol SystemFont: Font where TextStyle == UIFont.TextStyle {} 113 | 114 | public extension SystemFont { 115 | func font(forTextStyle textStyle: UIFont.TextStyle) -> UIFont { 116 | return fonts[textStyle]?.font ?? UIFont.default 117 | } 118 | } 119 | 120 | /// Dynamically scalable font which supports built in textstyle - `UIFont.TextStyle`. 121 | public protocol DynamicTypeFont: SystemFont { 122 | /// Dynamically scalled font for FontStyle. 123 | func preferredFont(forTextStyle textStyle: UIFont.TextStyle) -> UIFont 124 | 125 | /// Dynamically scalled font for FontStyle with maximumPointSize & traitCollection. 126 | func preferredFont(forTextStyle textStyle: UIFont.TextStyle, 127 | maximumPointSize: CGFloat, 128 | compatibleWith traitCollection: UITraitCollection?) -> UIFont 129 | } 130 | 131 | // MARK: - Creates dynamicFont 132 | 133 | public extension DynamicTypeFont { 134 | /// Dynamically scalled font for FontStyle. 135 | func preferredFont(forTextStyle textStyle: UIFont.TextStyle) -> UIFont { 136 | guard let font = fonts[textStyle]?.font else { 137 | return UIFont.preferredFont(forTextStyle: textStyle) 138 | } 139 | 140 | return UIFontMetrics(forTextStyle: textStyle).scaledFont(for: font) 141 | } 142 | 143 | /// Dynamically scalled font for FontStyle with maximumPointSize & traitCollection. 144 | func preferredFont(forTextStyle textStyle: UIFont.TextStyle, maximumPointSize: CGFloat, compatibleWith traitCollection: UITraitCollection? = nil) -> UIFont { 145 | guard let font = fonts[textStyle]?.font else { 146 | return UIFont.preferredFont(forTextStyle: textStyle, compatibleWith: traitCollection) 147 | } 148 | return UIFontMetrics(forTextStyle: textStyle).scaledFont(for: font, maximumPointSize: maximumPointSize, compatibleWith: traitCollection) 149 | } 150 | } 151 | 152 | /// DynamicTypeCustomTextStyleFont - Support font with custom font style. 153 | public protocol DynamicTypeCustomTextStyleFont: Font { 154 | func preferredFont(forTextStyle textStyle: TextStyle) -> UIFont 155 | func preferredFont(forTextStyle textStyle: TextStyle, 156 | maximumPointSize: CGFloat, 157 | compatibleWith traitCollection: UITraitCollection?) -> UIFont 158 | } 159 | -------------------------------------------------------------------------------- /Source/UIColor+Extension.swift: -------------------------------------------------------------------------------- 1 | // Doric 2 | // 3 | // Copyright (c) 2019 Jay K. 4 | // 5 | // Permission is hereby granted, free of charge, to any person obtaining a copy 6 | // of this software and associated documentation files (the "Software"), to deal 7 | // in the Software without restriction, including without limitation the rights 8 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | // copies of the Software, and to permit persons to whom the Software is 10 | // furnished to do so, subject to the following conditions: 11 | // 12 | // The above copyright notice and this permission notice shall be included in 13 | // all copies or substantial portions of the Software. 14 | // 15 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 21 | // THE SOFTWARE. 22 | 23 | import UIKit 24 | 25 | extension UIColor { 26 | /// Get white component of current color 27 | var whiteComponent: CGFloat { 28 | var white: CGFloat = 0.0 29 | getWhite(&white, alpha: nil) 30 | return white 31 | } 32 | } 33 | 34 | public extension UIColor { 35 | /// Creates color from hexadecimal string 36 | /// 37 | /// Example input string cab be with # prefix i.e. #FF00FF or FF00FF 38 | /// - Parameters: 39 | /// - hexString: Valid hexadecimal string 40 | /// - alpha: Alpha value of color, default is 1.0 41 | 42 | convenience init(_ hexString: String, alpha: CGFloat = 1.0) { 43 | let scanner = Scanner(string: hexString) 44 | scanner.scanLocation = hexString.hasPrefix("#") ? 1 : 0 45 | var intRGB: UInt64 = 0 46 | scanner.scanHexInt64(&intRGB) 47 | let red = (intRGB & 0xFF0000) >> 16 48 | let green = (intRGB & 0xFF00) >> 8 49 | let blue = intRGB & 0xFF 50 | self.init(red: CGFloat(red) / 0xFF, green: CGFloat(green) / 0xFF, blue: CGFloat(blue) / 0xFF, alpha: alpha) 51 | } 52 | 53 | /// hexadecimal (a hex triplet) representation of current color. 54 | var hexString: String { 55 | var red: CGFloat = 0.0 56 | var green: CGFloat = 0.0 57 | var blue: CGFloat = 0.0 58 | var alpha: CGFloat = 0.0 59 | getRed(&red, green: &green, blue: &blue, alpha: &alpha) 60 | return String(format: "#%02X%02X%02X", Int(red * 0xFF), Int(red * 0xFF), Int(green * 0xFF)) 61 | } 62 | } 63 | 64 | /// Color adjustment create shades and tints 65 | extension UIColor { 66 | /// Creates darker color by factor, adjusts brightness or saturation of color by factor 67 | /// 68 | /// Darker of black will be always black 69 | /// - Parameter factor: `factor` value should between 0.0 - 1.0 70 | /// - Returns: newly created color after adjustment 71 | func darker(by factor: CGFloat) -> UIColor { 72 | return adjustBrightnessOrSaturation(by: -factor) 73 | } 74 | 75 | /// Creates ligher color by factor, Adjusts brightness or saturation of color by factor 76 | /// 77 | /// Lighter of white will be always white 78 | /// - Parameter factor: `factor` value should between 0.0 - 1.0 79 | /// - Returns: newly created color after adjustment 80 | func lighter(by factor: CGFloat) -> UIColor { 81 | return adjustBrightnessOrSaturation(by: factor) 82 | } 83 | 84 | /// Adjusts brightness or saturation of color by factor 85 | /// 86 | /// - Parameter factor: factor should between 0.0 - 1.0 87 | /// - Returns: newly created color after adjustment 88 | fileprivate func adjustBrightnessOrSaturation(by factor: CGFloat) -> UIColor { 89 | var currentHue: CGFloat = 0, 90 | currentSaturation: CGFloat = 0, 91 | currentBrigthness: CGFloat = 0, 92 | currentAlpha: CGFloat = 0 93 | 94 | // Default return current color 95 | guard getHue(¤tHue, 96 | saturation: ¤tSaturation, 97 | brightness: ¤tBrigthness, 98 | alpha: ¤tAlpha) else { 99 | return self 100 | } 101 | 102 | // Adjust color by increasing brightness or reducing saturation and derived values are between 0.0 - 1.0 103 | if currentBrigthness < 1.0 { 104 | return UIColor(hue: currentHue, 105 | saturation: currentSaturation, 106 | brightness: max(min(currentBrigthness + factor * currentBrigthness, 1.0), 0.0), 107 | alpha: currentAlpha) 108 | } else { 109 | return UIColor(hue: currentHue, 110 | saturation: min(max(currentSaturation - factor * currentSaturation, 0.0), 1.0), 111 | brightness: currentBrigthness, 112 | alpha: currentAlpha) 113 | } 114 | } 115 | } 116 | -------------------------------------------------------------------------------- /Source/UIStackView+Border.swift: -------------------------------------------------------------------------------- 1 | // Doric 2 | // 3 | // Copyright (c) 2019 Jay K. 4 | // 5 | // Permission is hereby granted, free of charge, to any person obtaining a copy 6 | // of this software and associated documentation files (the "Software"), to deal 7 | // in the Software without restriction, including without limitation the rights 8 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | // copies of the Software, and to permit persons to whom the Software is 10 | // furnished to do so, subject to the following conditions: 11 | // 12 | // The above copyright notice and this permission notice shall be included in 13 | // all copies or substantial portions of the Software. 14 | // 15 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 21 | // THE SOFTWARE. 22 | 23 | import UIKit 24 | 25 | public extension UIStackView { 26 | /// Extension of `UIStackView` to create border. 27 | /// 28 | /// It just adds one view with border, This method is part of UI debug helper tools. 29 | /// - Parameters: 30 | /// - color: Color for border, by default 'black' color. 31 | /// - width: width of border, by default 1.0. 32 | func enableBorder(_ color: UIColor = UIColor.black, width: CGFloat = 1.0) { 33 | let borderView = UIView(frame: CGRect.zero) 34 | borderView.translatesAutoresizingMaskIntoConstraints = false 35 | borderView.layer.borderColor = color.cgColor 36 | borderView.layer.borderWidth = width 37 | addSubview(borderView) 38 | borderView.anchorEdges(self) 39 | } 40 | } 41 | 42 | public extension UIView { 43 | /// Add recursive border to view and all its subviews 44 | /// 45 | /// This method is part of UI debug helper tools. 46 | /// - Parameters: 47 | /// - view: target view in which borders will be enabled. 48 | /// - color: Color for border, by default 'black' color. 49 | /// - width: width of border, by default 1.0. 50 | static func recursiveEnableBorder(_ view: UIView, color: UIColor = UIColor.black, width: CGFloat = 1.0) { 51 | view.layer.borderColor = color.cgColor 52 | view.layer.borderWidth = width 53 | 54 | if let stackView = view as? UIStackView { 55 | stackView.enableBorder(color, width: width) 56 | stackView.arrangedSubviews.forEach { arrangedView in 57 | UIView.recursiveEnableBorder(arrangedView, color: color, width: width) 58 | } 59 | } else { 60 | view.subviews.forEach { subview in 61 | UIView.recursiveEnableBorder(subview) 62 | } 63 | } 64 | } 65 | } 66 | -------------------------------------------------------------------------------- /Source/UIView+Guide.swift: -------------------------------------------------------------------------------- 1 | // Doric 2 | // 3 | // Copyright (c) 2019 Jay K. 4 | // 5 | // Permission is hereby granted, free of charge, to any person obtaining a copy 6 | // of this software and associated documentation files (the "Software"), to deal 7 | // in the Software without restriction, including without limitation the rights 8 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | // copies of the Software, and to permit persons to whom the Software is 10 | // furnished to do so, subject to the following conditions: 11 | // 12 | // The above copyright notice and this permission notice shall be included in 13 | // all copies or substantial portions of the Software. 14 | // 15 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 21 | // THE SOFTWARE. 22 | 23 | import UIKit 24 | 25 | public extension UIView { 26 | /** 27 | Shows guide for an instance of view, Guideline adds single line view with constraints equivalents to edges, dimentions, baselines. 28 | 29 | Guideline is part of UI debug helper tools. 30 | Example usage can be as below, as it adds lines using autolayouts it is expected target view should be added to its superview. 31 | 32 | ``` 33 | let label = UILabel() 34 | ... 35 | ... 36 | // Creates guidelines set to be displayed 37 | let guidelines: UIView.Guideline = [.leading, .firstBaseline, .bottom] 38 | 39 | // Shows guideline on label 40 | label.showGuide(guideline: guidelines) 41 | 42 | */ 43 | struct Guideline: OptionSet { 44 | public let rawValue: Int 45 | 46 | public init(rawValue: Int) { 47 | self.rawValue = rawValue 48 | } 49 | 50 | /// Guide for top edge. 51 | public static let top = Guideline(rawValue: 1 << 0) 52 | 53 | /// Guide for bottom edge. 54 | public static let bottom = Guideline(rawValue: 1 << 1) 55 | 56 | /// Guide for leading edge. 57 | public static let leading = Guideline(rawValue: 1 << 2) 58 | 59 | /// Guide for trailing edge. 60 | public static let trailing = Guideline(rawValue: 1 << 3) 61 | 62 | /// Guide for firstBaseline. 63 | public static let firstBaseline = Guideline(rawValue: 1 << 4) 64 | 65 | /// Guide for lastBaseline. 66 | public static let lastBaseline = Guideline(rawValue: 1 << 5) 67 | 68 | /// Guide for height dimention. 69 | public static let height = Guideline(rawValue: 1 << 6) 70 | 71 | /// Guide for width dimention. 72 | public static let width = Guideline(rawValue: 1 << 7) 73 | 74 | /// Guide for top, bottom, leading edges. 75 | public static let basic: Guideline = [.top, .bottom, .leading] 76 | 77 | /// Guide for all edges, dimentions, baselines. 78 | public static let all: Guideline = [.top, .bottom, .leading, .trailing, .firstBaseline, .lastBaseline, .height, .width] 79 | } 80 | 81 | /// One pixel, represents height for guide. 82 | private struct Pixel: LayoutValueRepresentable { 83 | public let rawValue: CGFloat = Space.pixel 84 | } 85 | 86 | // swiftlint:disable function_body_length 87 | 88 | /// Show guide for view with guideline options 89 | /// 90 | /// - Parameters: 91 | /// - guideline: Guidelines to be displayed. By default options ```[.top, .bottom, .leading]``` 92 | /// - color: Color for guideline 93 | 94 | func showGuide(guideline: Guideline = Guideline.basic, color: UIColor = UIColor.black) { 95 | func createGuideView() -> UIView { 96 | let guide = UIView(frame: CGRect.zero) 97 | guide.backgroundColor = color 98 | return guide 99 | } 100 | 101 | let multiplier: CGFloat = 1.2 102 | let guideSize = LayoutRelation.equalTo(Pixel()) 103 | 104 | if guideline.contains(.height) { 105 | let heightGuide = createGuideView() 106 | addSubview(heightGuide) 107 | heightGuide.anchorCenter(self) 108 | heightGuide.anchorWidth(guideSize) 109 | heightGuide.anchorHeight(self, multiplier: multiplier) 110 | } 111 | 112 | if guideline.contains(.width) { 113 | let widthGuide = createGuideView() 114 | addSubview(widthGuide) 115 | widthGuide.anchorCenter(self) 116 | widthGuide.anchorHeight(guideSize) 117 | widthGuide.anchorWidth(self, multiplier: multiplier) 118 | } 119 | 120 | if guideline.contains(.leading) { 121 | let leftGuide = createGuideView() 122 | addSubview(leftGuide) 123 | leftGuide.anchorLeading(self) 124 | leftGuide.anchorCenterY(self) 125 | leftGuide.anchorWidth(guideSize) 126 | leftGuide.anchorHeight(self, multiplier: multiplier) 127 | } 128 | 129 | if guideline.contains(.trailing) { 130 | let rightGuide = createGuideView() 131 | addSubview(rightGuide) 132 | rightGuide.anchorTrailing(self) 133 | rightGuide.anchorCenterY(self) 134 | rightGuide.anchorWidth(guideSize) 135 | rightGuide.anchorHeight(self, multiplier: multiplier) 136 | } 137 | 138 | if guideline.contains(.top) { 139 | let topGuide = createGuideView() 140 | addSubview(topGuide) 141 | topGuide.anchorTop(self) 142 | topGuide.anchorCenterX(self) 143 | topGuide.anchorHeight(guideSize) 144 | topGuide.anchorWidth(self, multiplier: multiplier) 145 | } 146 | 147 | if guideline.contains(.bottom) { 148 | let bottomGuide = createGuideView() 149 | addSubview(bottomGuide) 150 | bottomGuide.anchorBottom(self) 151 | bottomGuide.anchorCenterX(self) 152 | bottomGuide.anchorHeight(guideSize) 153 | bottomGuide.anchorWidth(self, multiplier: multiplier) 154 | } 155 | 156 | if guideline.contains(.firstBaseline) { 157 | let firstBaselineGuide = createGuideView() 158 | addSubview(firstBaselineGuide) 159 | firstBaselineGuide.anchorFirstBaseline(self) 160 | firstBaselineGuide.anchorCenterX(self) 161 | firstBaselineGuide.anchorHeight(guideSize) 162 | firstBaselineGuide.anchorWidth(self, multiplier: multiplier) 163 | } 164 | 165 | if guideline.contains(.lastBaseline) { 166 | let lastBaselineGuide = createGuideView() 167 | addSubview(lastBaselineGuide) 168 | lastBaselineGuide.anchorLastBaseline(self) 169 | lastBaselineGuide.anchorCenterX(self) 170 | lastBaselineGuide.anchorHeight(guideSize) 171 | lastBaselineGuide.anchorWidth(self, multiplier: multiplier) 172 | } 173 | } 174 | 175 | // swiftlint:enable function_body_length 176 | } 177 | -------------------------------------------------------------------------------- /Source/internal-icon-close.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jayeshk/Doric/2629fb2d1328fdbf7d76a8583e3931caa8238168/Source/internal-icon-close.png -------------------------------------------------------------------------------- /demo-screenshot.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jayeshk/Doric/2629fb2d1328fdbf7d76a8583e3931caa8238168/demo-screenshot.png -------------------------------------------------------------------------------- /docs/_config.yml: -------------------------------------------------------------------------------- 1 | theme: jekyll-theme-slate -------------------------------------------------------------------------------- /docs/badge.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | documentation 17 | 18 | 19 | documentation 20 | 21 | 22 | 94% 23 | 24 | 25 | 94% 26 | 27 | 28 | 29 | -------------------------------------------------------------------------------- /docs/css/highlight.css: -------------------------------------------------------------------------------- 1 | /* Credit to https://gist.github.com/wataru420/2048287 */ 2 | .highlight { 3 | /* Comment */ 4 | /* Error */ 5 | /* Keyword */ 6 | /* Operator */ 7 | /* Comment.Multiline */ 8 | /* Comment.Preproc */ 9 | /* Comment.Single */ 10 | /* Comment.Special */ 11 | /* Generic.Deleted */ 12 | /* Generic.Deleted.Specific */ 13 | /* Generic.Emph */ 14 | /* Generic.Error */ 15 | /* Generic.Heading */ 16 | /* Generic.Inserted */ 17 | /* Generic.Inserted.Specific */ 18 | /* Generic.Output */ 19 | /* Generic.Prompt */ 20 | /* Generic.Strong */ 21 | /* Generic.Subheading */ 22 | /* Generic.Traceback */ 23 | /* Keyword.Constant */ 24 | /* Keyword.Declaration */ 25 | /* Keyword.Pseudo */ 26 | /* Keyword.Reserved */ 27 | /* Keyword.Type */ 28 | /* Literal.Number */ 29 | /* Literal.String */ 30 | /* Name.Attribute */ 31 | /* Name.Builtin */ 32 | /* Name.Class */ 33 | /* Name.Constant */ 34 | /* Name.Entity */ 35 | /* Name.Exception */ 36 | /* Name.Function */ 37 | /* Name.Namespace */ 38 | /* Name.Tag */ 39 | /* Name.Variable */ 40 | /* Operator.Word */ 41 | /* Text.Whitespace */ 42 | /* Literal.Number.Float */ 43 | /* Literal.Number.Hex */ 44 | /* Literal.Number.Integer */ 45 | /* Literal.Number.Oct */ 46 | /* Literal.String.Backtick */ 47 | /* Literal.String.Char */ 48 | /* Literal.String.Doc */ 49 | /* Literal.String.Double */ 50 | /* Literal.String.Escape */ 51 | /* Literal.String.Heredoc */ 52 | /* Literal.String.Interpol */ 53 | /* Literal.String.Other */ 54 | /* Literal.String.Regex */ 55 | /* Literal.String.Single */ 56 | /* Literal.String.Symbol */ 57 | /* Name.Builtin.Pseudo */ 58 | /* Name.Variable.Class */ 59 | /* Name.Variable.Global */ 60 | /* Name.Variable.Instance */ 61 | /* Literal.Number.Integer.Long */ } 62 | .highlight .c { 63 | color: #999988; 64 | font-style: italic; } 65 | .highlight .err { 66 | color: #a61717; 67 | background-color: #e3d2d2; } 68 | .highlight .k { 69 | color: #000000; 70 | font-weight: bold; } 71 | .highlight .o { 72 | color: #000000; 73 | font-weight: bold; } 74 | .highlight .cm { 75 | color: #999988; 76 | font-style: italic; } 77 | .highlight .cp { 78 | color: #999999; 79 | font-weight: bold; } 80 | .highlight .c1 { 81 | color: #999988; 82 | font-style: italic; } 83 | .highlight .cs { 84 | color: #999999; 85 | font-weight: bold; 86 | font-style: italic; } 87 | .highlight .gd { 88 | color: #000000; 89 | background-color: #ffdddd; } 90 | .highlight .gd .x { 91 | color: #000000; 92 | background-color: #ffaaaa; } 93 | .highlight .ge { 94 | color: #000000; 95 | font-style: italic; } 96 | .highlight .gr { 97 | color: #aa0000; } 98 | .highlight .gh { 99 | color: #999999; } 100 | .highlight .gi { 101 | color: #000000; 102 | background-color: #ddffdd; } 103 | .highlight .gi .x { 104 | color: #000000; 105 | background-color: #aaffaa; } 106 | .highlight .go { 107 | color: #888888; } 108 | .highlight .gp { 109 | color: #555555; } 110 | .highlight .gs { 111 | font-weight: bold; } 112 | .highlight .gu { 113 | color: #aaaaaa; } 114 | .highlight .gt { 115 | color: #aa0000; } 116 | .highlight .kc { 117 | color: #000000; 118 | font-weight: bold; } 119 | .highlight .kd { 120 | color: #000000; 121 | font-weight: bold; } 122 | .highlight .kp { 123 | color: #000000; 124 | font-weight: bold; } 125 | .highlight .kr { 126 | color: #000000; 127 | font-weight: bold; } 128 | .highlight .kt { 129 | color: #445588; } 130 | .highlight .m { 131 | color: #009999; } 132 | .highlight .s { 133 | color: #d14; } 134 | .highlight .na { 135 | color: #008080; } 136 | .highlight .nb { 137 | color: #0086B3; } 138 | .highlight .nc { 139 | color: #445588; 140 | font-weight: bold; } 141 | .highlight .no { 142 | color: #008080; } 143 | .highlight .ni { 144 | color: #800080; } 145 | .highlight .ne { 146 | color: #990000; 147 | font-weight: bold; } 148 | .highlight .nf { 149 | color: #990000; } 150 | .highlight .nn { 151 | color: #555555; } 152 | .highlight .nt { 153 | color: #000080; } 154 | .highlight .nv { 155 | color: #008080; } 156 | .highlight .ow { 157 | color: #000000; 158 | font-weight: bold; } 159 | .highlight .w { 160 | color: #bbbbbb; } 161 | .highlight .mf { 162 | color: #009999; } 163 | .highlight .mh { 164 | color: #009999; } 165 | .highlight .mi { 166 | color: #009999; } 167 | .highlight .mo { 168 | color: #009999; } 169 | .highlight .sb { 170 | color: #d14; } 171 | .highlight .sc { 172 | color: #d14; } 173 | .highlight .sd { 174 | color: #d14; } 175 | .highlight .s2 { 176 | color: #d14; } 177 | .highlight .se { 178 | color: #d14; } 179 | .highlight .sh { 180 | color: #d14; } 181 | .highlight .si { 182 | color: #d14; } 183 | .highlight .sx { 184 | color: #d14; } 185 | .highlight .sr { 186 | color: #009926; } 187 | .highlight .s1 { 188 | color: #d14; } 189 | .highlight .ss { 190 | color: #990073; } 191 | .highlight .bp { 192 | color: #999999; } 193 | .highlight .vc { 194 | color: #008080; } 195 | .highlight .vg { 196 | color: #008080; } 197 | .highlight .vi { 198 | color: #008080; } 199 | .highlight .il { 200 | color: #009999; } 201 | -------------------------------------------------------------------------------- /docs/css/jazzy.css: -------------------------------------------------------------------------------- 1 | html, body, div, span, h1, h3, h4, p, a, code, em, img, ul, li, table, tbody, tr, td { 2 | background: transparent; 3 | border: 0; 4 | margin: 0; 5 | outline: 0; 6 | padding: 0; 7 | vertical-align: baseline; } 8 | 9 | body { 10 | background-color: #f2f2f2; 11 | font-family: Helvetica, freesans, Arial, sans-serif; 12 | font-size: 14px; 13 | -webkit-font-smoothing: subpixel-antialiased; 14 | word-wrap: break-word; } 15 | 16 | h1, h2, h3 { 17 | margin-top: 0.8em; 18 | margin-bottom: 0.3em; 19 | font-weight: 100; 20 | color: black; } 21 | 22 | h1 { 23 | font-size: 2.5em; } 24 | 25 | h2 { 26 | font-size: 2em; 27 | border-bottom: 1px solid #e2e2e2; } 28 | 29 | h4 { 30 | font-size: 13px; 31 | line-height: 1.5; 32 | margin-top: 21px; } 33 | 34 | h5 { 35 | font-size: 1.1em; } 36 | 37 | h6 { 38 | font-size: 1.1em; 39 | color: #777; } 40 | 41 | .section-name { 42 | color: gray; 43 | display: block; 44 | font-family: Helvetica; 45 | font-size: 22px; 46 | font-weight: 100; 47 | margin-bottom: 15px; } 48 | 49 | pre, code { 50 | font: 0.95em Menlo, monospace; 51 | color: #777; 52 | word-wrap: normal; } 53 | 54 | p code, li code { 55 | background-color: #eee; 56 | padding: 2px 4px; 57 | border-radius: 4px; } 58 | 59 | a { 60 | color: #0088cc; 61 | text-decoration: none; } 62 | 63 | ul { 64 | padding-left: 15px; } 65 | 66 | li { 67 | line-height: 1.8em; } 68 | 69 | img { 70 | max-width: 100%; } 71 | 72 | blockquote { 73 | margin-left: 0; 74 | padding: 0 10px; 75 | border-left: 4px solid #ccc; } 76 | 77 | .content-wrapper { 78 | margin: 0 auto; 79 | width: 980px; } 80 | 81 | header { 82 | font-size: 0.85em; 83 | line-height: 26px; 84 | background-color: #414141; 85 | position: fixed; 86 | width: 100%; 87 | z-index: 1; } 88 | header img { 89 | padding-right: 6px; 90 | vertical-align: -4px; 91 | height: 16px; } 92 | header a { 93 | color: #fff; } 94 | header p { 95 | float: left; 96 | color: #999; } 97 | header .header-right { 98 | float: right; 99 | margin-left: 16px; } 100 | 101 | #breadcrumbs { 102 | background-color: #f2f2f2; 103 | height: 27px; 104 | padding-top: 17px; 105 | position: fixed; 106 | width: 100%; 107 | z-index: 1; 108 | margin-top: 26px; } 109 | #breadcrumbs #carat { 110 | height: 10px; 111 | margin: 0 5px; } 112 | 113 | .sidebar { 114 | background-color: #f9f9f9; 115 | border: 1px solid #e2e2e2; 116 | overflow-y: auto; 117 | overflow-x: hidden; 118 | position: fixed; 119 | top: 70px; 120 | bottom: 0; 121 | width: 230px; 122 | word-wrap: normal; } 123 | 124 | .nav-groups { 125 | list-style-type: none; 126 | background: #fff; 127 | padding-left: 0; } 128 | 129 | .nav-group-name { 130 | border-bottom: 1px solid #e2e2e2; 131 | font-size: 1.1em; 132 | font-weight: 100; 133 | padding: 15px 0 15px 20px; } 134 | .nav-group-name > a { 135 | color: #333; } 136 | 137 | .nav-group-tasks { 138 | margin-top: 5px; } 139 | 140 | .nav-group-task { 141 | font-size: 0.9em; 142 | list-style-type: none; 143 | white-space: nowrap; } 144 | .nav-group-task a { 145 | color: #888; } 146 | 147 | .main-content { 148 | background-color: #fff; 149 | border: 1px solid #e2e2e2; 150 | margin-left: 246px; 151 | position: absolute; 152 | overflow: hidden; 153 | padding-bottom: 60px; 154 | top: 70px; 155 | width: 734px; } 156 | .main-content p, .main-content a, .main-content code, .main-content em, .main-content ul, .main-content table, .main-content blockquote { 157 | margin-bottom: 1em; } 158 | .main-content p { 159 | line-height: 1.8em; } 160 | .main-content section .section:first-child { 161 | margin-top: 0; 162 | padding-top: 0; } 163 | .main-content section .task-group-section .task-group:first-of-type { 164 | padding-top: 10px; } 165 | .main-content section .task-group-section .task-group:first-of-type .section-name { 166 | padding-top: 15px; } 167 | .main-content section .heading:before { 168 | content: ""; 169 | display: block; 170 | padding-top: 70px; 171 | margin: -70px 0 0; } 172 | 173 | .section { 174 | padding: 0 25px; } 175 | 176 | .highlight { 177 | background-color: #eee; 178 | padding: 10px 12px; 179 | border: 1px solid #e2e2e2; 180 | border-radius: 4px; 181 | overflow-x: auto; } 182 | 183 | .declaration .highlight { 184 | overflow-x: initial; 185 | padding: 0 40px 40px 0; 186 | margin-bottom: -25px; 187 | background-color: transparent; 188 | border: none; } 189 | 190 | .section-name { 191 | margin: 0; 192 | margin-left: 18px; } 193 | 194 | .task-group-section { 195 | padding-left: 6px; 196 | border-top: 1px solid #e2e2e2; } 197 | 198 | .task-group { 199 | padding-top: 0px; } 200 | 201 | .task-name-container a[name]:before { 202 | content: ""; 203 | display: block; 204 | padding-top: 70px; 205 | margin: -70px 0 0; } 206 | 207 | .item { 208 | padding-top: 8px; 209 | width: 100%; 210 | list-style-type: none; } 211 | .item a[name]:before { 212 | content: ""; 213 | display: block; 214 | padding-top: 70px; 215 | margin: -70px 0 0; } 216 | .item code { 217 | background-color: transparent; 218 | padding: 0; } 219 | .item .token { 220 | padding-left: 3px; 221 | margin-left: 15px; 222 | font-size: 11.9px; } 223 | .item .declaration-note { 224 | font-size: .85em; 225 | color: gray; 226 | font-style: italic; } 227 | 228 | .pointer-container { 229 | border-bottom: 1px solid #e2e2e2; 230 | left: -23px; 231 | padding-bottom: 13px; 232 | position: relative; 233 | width: 110%; } 234 | 235 | .pointer { 236 | background: #f9f9f9; 237 | border-left: 1px solid #e2e2e2; 238 | border-top: 1px solid #e2e2e2; 239 | height: 12px; 240 | left: 21px; 241 | top: -7px; 242 | -webkit-transform: rotate(45deg); 243 | -moz-transform: rotate(45deg); 244 | -o-transform: rotate(45deg); 245 | transform: rotate(45deg); 246 | position: absolute; 247 | width: 12px; } 248 | 249 | .height-container { 250 | display: none; 251 | left: -25px; 252 | padding: 0 25px; 253 | position: relative; 254 | width: 100%; 255 | overflow: hidden; } 256 | .height-container .section { 257 | background: #f9f9f9; 258 | border-bottom: 1px solid #e2e2e2; 259 | left: -25px; 260 | position: relative; 261 | width: 100%; 262 | padding-top: 10px; 263 | padding-bottom: 5px; } 264 | 265 | .aside, .language { 266 | padding: 6px 12px; 267 | margin: 12px 0; 268 | border-left: 5px solid #dddddd; 269 | overflow-y: hidden; } 270 | .aside .aside-title, .language .aside-title { 271 | font-size: 9px; 272 | letter-spacing: 2px; 273 | text-transform: uppercase; 274 | padding-bottom: 0; 275 | margin: 0; 276 | color: #aaa; 277 | -webkit-user-select: none; } 278 | .aside p:last-child, .language p:last-child { 279 | margin-bottom: 0; } 280 | 281 | .language { 282 | border-left: 5px solid #cde9f4; } 283 | .language .aside-title { 284 | color: #4b8afb; } 285 | 286 | .aside-warning { 287 | border-left: 5px solid #ff6666; } 288 | .aside-warning .aside-title { 289 | color: #ff0000; } 290 | 291 | .graybox { 292 | border-collapse: collapse; 293 | width: 100%; } 294 | .graybox p { 295 | margin: 0; 296 | word-break: break-word; 297 | min-width: 50px; } 298 | .graybox td { 299 | border: 1px solid #e2e2e2; 300 | padding: 5px 25px 5px 10px; 301 | vertical-align: middle; } 302 | .graybox tr td:first-of-type { 303 | text-align: right; 304 | padding: 7px; 305 | vertical-align: top; 306 | word-break: normal; 307 | width: 40px; } 308 | 309 | .slightly-smaller { 310 | font-size: 0.9em; } 311 | 312 | #footer { 313 | position: absolute; 314 | bottom: 10px; 315 | margin-left: 25px; } 316 | #footer p { 317 | margin: 0; 318 | color: #aaa; 319 | font-size: 0.8em; } 320 | 321 | html.dash header, html.dash #breadcrumbs, html.dash .sidebar { 322 | display: none; } 323 | html.dash .main-content { 324 | width: 980px; 325 | margin-left: 0; 326 | border: none; 327 | width: 100%; 328 | top: 0; 329 | padding-bottom: 0; } 330 | html.dash .height-container { 331 | display: block; } 332 | html.dash .item .token { 333 | margin-left: 0; } 334 | html.dash .content-wrapper { 335 | width: auto; } 336 | html.dash #footer { 337 | position: static; } 338 | -------------------------------------------------------------------------------- /docs/docsets/Doric.docset/Contents/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleIdentifier 6 | com.jazzy.doric 7 | CFBundleName 8 | Doric 9 | DocSetPlatformFamily 10 | doric 11 | isDashDocset 12 | 13 | dashIndexFilePath 14 | index.html 15 | isJavaScriptEnabled 16 | 17 | DashDocSetFamily 18 | dashtoc 19 | 20 | 21 | -------------------------------------------------------------------------------- /docs/docsets/Doric.docset/Contents/Resources/Documents/_config.yml: -------------------------------------------------------------------------------- 1 | theme: jekyll-theme-slate -------------------------------------------------------------------------------- /docs/docsets/Doric.docset/Contents/Resources/Documents/badge.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | documentation 17 | 18 | 19 | documentation 20 | 21 | 22 | 94% 23 | 24 | 25 | 94% 26 | 27 | 28 | 29 | -------------------------------------------------------------------------------- /docs/docsets/Doric.docset/Contents/Resources/Documents/css/highlight.css: -------------------------------------------------------------------------------- 1 | /* Credit to https://gist.github.com/wataru420/2048287 */ 2 | .highlight { 3 | /* Comment */ 4 | /* Error */ 5 | /* Keyword */ 6 | /* Operator */ 7 | /* Comment.Multiline */ 8 | /* Comment.Preproc */ 9 | /* Comment.Single */ 10 | /* Comment.Special */ 11 | /* Generic.Deleted */ 12 | /* Generic.Deleted.Specific */ 13 | /* Generic.Emph */ 14 | /* Generic.Error */ 15 | /* Generic.Heading */ 16 | /* Generic.Inserted */ 17 | /* Generic.Inserted.Specific */ 18 | /* Generic.Output */ 19 | /* Generic.Prompt */ 20 | /* Generic.Strong */ 21 | /* Generic.Subheading */ 22 | /* Generic.Traceback */ 23 | /* Keyword.Constant */ 24 | /* Keyword.Declaration */ 25 | /* Keyword.Pseudo */ 26 | /* Keyword.Reserved */ 27 | /* Keyword.Type */ 28 | /* Literal.Number */ 29 | /* Literal.String */ 30 | /* Name.Attribute */ 31 | /* Name.Builtin */ 32 | /* Name.Class */ 33 | /* Name.Constant */ 34 | /* Name.Entity */ 35 | /* Name.Exception */ 36 | /* Name.Function */ 37 | /* Name.Namespace */ 38 | /* Name.Tag */ 39 | /* Name.Variable */ 40 | /* Operator.Word */ 41 | /* Text.Whitespace */ 42 | /* Literal.Number.Float */ 43 | /* Literal.Number.Hex */ 44 | /* Literal.Number.Integer */ 45 | /* Literal.Number.Oct */ 46 | /* Literal.String.Backtick */ 47 | /* Literal.String.Char */ 48 | /* Literal.String.Doc */ 49 | /* Literal.String.Double */ 50 | /* Literal.String.Escape */ 51 | /* Literal.String.Heredoc */ 52 | /* Literal.String.Interpol */ 53 | /* Literal.String.Other */ 54 | /* Literal.String.Regex */ 55 | /* Literal.String.Single */ 56 | /* Literal.String.Symbol */ 57 | /* Name.Builtin.Pseudo */ 58 | /* Name.Variable.Class */ 59 | /* Name.Variable.Global */ 60 | /* Name.Variable.Instance */ 61 | /* Literal.Number.Integer.Long */ } 62 | .highlight .c { 63 | color: #999988; 64 | font-style: italic; } 65 | .highlight .err { 66 | color: #a61717; 67 | background-color: #e3d2d2; } 68 | .highlight .k { 69 | color: #000000; 70 | font-weight: bold; } 71 | .highlight .o { 72 | color: #000000; 73 | font-weight: bold; } 74 | .highlight .cm { 75 | color: #999988; 76 | font-style: italic; } 77 | .highlight .cp { 78 | color: #999999; 79 | font-weight: bold; } 80 | .highlight .c1 { 81 | color: #999988; 82 | font-style: italic; } 83 | .highlight .cs { 84 | color: #999999; 85 | font-weight: bold; 86 | font-style: italic; } 87 | .highlight .gd { 88 | color: #000000; 89 | background-color: #ffdddd; } 90 | .highlight .gd .x { 91 | color: #000000; 92 | background-color: #ffaaaa; } 93 | .highlight .ge { 94 | color: #000000; 95 | font-style: italic; } 96 | .highlight .gr { 97 | color: #aa0000; } 98 | .highlight .gh { 99 | color: #999999; } 100 | .highlight .gi { 101 | color: #000000; 102 | background-color: #ddffdd; } 103 | .highlight .gi .x { 104 | color: #000000; 105 | background-color: #aaffaa; } 106 | .highlight .go { 107 | color: #888888; } 108 | .highlight .gp { 109 | color: #555555; } 110 | .highlight .gs { 111 | font-weight: bold; } 112 | .highlight .gu { 113 | color: #aaaaaa; } 114 | .highlight .gt { 115 | color: #aa0000; } 116 | .highlight .kc { 117 | color: #000000; 118 | font-weight: bold; } 119 | .highlight .kd { 120 | color: #000000; 121 | font-weight: bold; } 122 | .highlight .kp { 123 | color: #000000; 124 | font-weight: bold; } 125 | .highlight .kr { 126 | color: #000000; 127 | font-weight: bold; } 128 | .highlight .kt { 129 | color: #445588; } 130 | .highlight .m { 131 | color: #009999; } 132 | .highlight .s { 133 | color: #d14; } 134 | .highlight .na { 135 | color: #008080; } 136 | .highlight .nb { 137 | color: #0086B3; } 138 | .highlight .nc { 139 | color: #445588; 140 | font-weight: bold; } 141 | .highlight .no { 142 | color: #008080; } 143 | .highlight .ni { 144 | color: #800080; } 145 | .highlight .ne { 146 | color: #990000; 147 | font-weight: bold; } 148 | .highlight .nf { 149 | color: #990000; } 150 | .highlight .nn { 151 | color: #555555; } 152 | .highlight .nt { 153 | color: #000080; } 154 | .highlight .nv { 155 | color: #008080; } 156 | .highlight .ow { 157 | color: #000000; 158 | font-weight: bold; } 159 | .highlight .w { 160 | color: #bbbbbb; } 161 | .highlight .mf { 162 | color: #009999; } 163 | .highlight .mh { 164 | color: #009999; } 165 | .highlight .mi { 166 | color: #009999; } 167 | .highlight .mo { 168 | color: #009999; } 169 | .highlight .sb { 170 | color: #d14; } 171 | .highlight .sc { 172 | color: #d14; } 173 | .highlight .sd { 174 | color: #d14; } 175 | .highlight .s2 { 176 | color: #d14; } 177 | .highlight .se { 178 | color: #d14; } 179 | .highlight .sh { 180 | color: #d14; } 181 | .highlight .si { 182 | color: #d14; } 183 | .highlight .sx { 184 | color: #d14; } 185 | .highlight .sr { 186 | color: #009926; } 187 | .highlight .s1 { 188 | color: #d14; } 189 | .highlight .ss { 190 | color: #990073; } 191 | .highlight .bp { 192 | color: #999999; } 193 | .highlight .vc { 194 | color: #008080; } 195 | .highlight .vg { 196 | color: #008080; } 197 | .highlight .vi { 198 | color: #008080; } 199 | .highlight .il { 200 | color: #009999; } 201 | -------------------------------------------------------------------------------- /docs/docsets/Doric.docset/Contents/Resources/Documents/css/jazzy.css: -------------------------------------------------------------------------------- 1 | html, body, div, span, h1, h3, h4, p, a, code, em, img, ul, li, table, tbody, tr, td { 2 | background: transparent; 3 | border: 0; 4 | margin: 0; 5 | outline: 0; 6 | padding: 0; 7 | vertical-align: baseline; } 8 | 9 | body { 10 | background-color: #f2f2f2; 11 | font-family: Helvetica, freesans, Arial, sans-serif; 12 | font-size: 14px; 13 | -webkit-font-smoothing: subpixel-antialiased; 14 | word-wrap: break-word; } 15 | 16 | h1, h2, h3 { 17 | margin-top: 0.8em; 18 | margin-bottom: 0.3em; 19 | font-weight: 100; 20 | color: black; } 21 | 22 | h1 { 23 | font-size: 2.5em; } 24 | 25 | h2 { 26 | font-size: 2em; 27 | border-bottom: 1px solid #e2e2e2; } 28 | 29 | h4 { 30 | font-size: 13px; 31 | line-height: 1.5; 32 | margin-top: 21px; } 33 | 34 | h5 { 35 | font-size: 1.1em; } 36 | 37 | h6 { 38 | font-size: 1.1em; 39 | color: #777; } 40 | 41 | .section-name { 42 | color: gray; 43 | display: block; 44 | font-family: Helvetica; 45 | font-size: 22px; 46 | font-weight: 100; 47 | margin-bottom: 15px; } 48 | 49 | pre, code { 50 | font: 0.95em Menlo, monospace; 51 | color: #777; 52 | word-wrap: normal; } 53 | 54 | p code, li code { 55 | background-color: #eee; 56 | padding: 2px 4px; 57 | border-radius: 4px; } 58 | 59 | a { 60 | color: #0088cc; 61 | text-decoration: none; } 62 | 63 | ul { 64 | padding-left: 15px; } 65 | 66 | li { 67 | line-height: 1.8em; } 68 | 69 | img { 70 | max-width: 100%; } 71 | 72 | blockquote { 73 | margin-left: 0; 74 | padding: 0 10px; 75 | border-left: 4px solid #ccc; } 76 | 77 | .content-wrapper { 78 | margin: 0 auto; 79 | width: 980px; } 80 | 81 | header { 82 | font-size: 0.85em; 83 | line-height: 26px; 84 | background-color: #414141; 85 | position: fixed; 86 | width: 100%; 87 | z-index: 1; } 88 | header img { 89 | padding-right: 6px; 90 | vertical-align: -4px; 91 | height: 16px; } 92 | header a { 93 | color: #fff; } 94 | header p { 95 | float: left; 96 | color: #999; } 97 | header .header-right { 98 | float: right; 99 | margin-left: 16px; } 100 | 101 | #breadcrumbs { 102 | background-color: #f2f2f2; 103 | height: 27px; 104 | padding-top: 17px; 105 | position: fixed; 106 | width: 100%; 107 | z-index: 1; 108 | margin-top: 26px; } 109 | #breadcrumbs #carat { 110 | height: 10px; 111 | margin: 0 5px; } 112 | 113 | .sidebar { 114 | background-color: #f9f9f9; 115 | border: 1px solid #e2e2e2; 116 | overflow-y: auto; 117 | overflow-x: hidden; 118 | position: fixed; 119 | top: 70px; 120 | bottom: 0; 121 | width: 230px; 122 | word-wrap: normal; } 123 | 124 | .nav-groups { 125 | list-style-type: none; 126 | background: #fff; 127 | padding-left: 0; } 128 | 129 | .nav-group-name { 130 | border-bottom: 1px solid #e2e2e2; 131 | font-size: 1.1em; 132 | font-weight: 100; 133 | padding: 15px 0 15px 20px; } 134 | .nav-group-name > a { 135 | color: #333; } 136 | 137 | .nav-group-tasks { 138 | margin-top: 5px; } 139 | 140 | .nav-group-task { 141 | font-size: 0.9em; 142 | list-style-type: none; 143 | white-space: nowrap; } 144 | .nav-group-task a { 145 | color: #888; } 146 | 147 | .main-content { 148 | background-color: #fff; 149 | border: 1px solid #e2e2e2; 150 | margin-left: 246px; 151 | position: absolute; 152 | overflow: hidden; 153 | padding-bottom: 60px; 154 | top: 70px; 155 | width: 734px; } 156 | .main-content p, .main-content a, .main-content code, .main-content em, .main-content ul, .main-content table, .main-content blockquote { 157 | margin-bottom: 1em; } 158 | .main-content p { 159 | line-height: 1.8em; } 160 | .main-content section .section:first-child { 161 | margin-top: 0; 162 | padding-top: 0; } 163 | .main-content section .task-group-section .task-group:first-of-type { 164 | padding-top: 10px; } 165 | .main-content section .task-group-section .task-group:first-of-type .section-name { 166 | padding-top: 15px; } 167 | .main-content section .heading:before { 168 | content: ""; 169 | display: block; 170 | padding-top: 70px; 171 | margin: -70px 0 0; } 172 | 173 | .section { 174 | padding: 0 25px; } 175 | 176 | .highlight { 177 | background-color: #eee; 178 | padding: 10px 12px; 179 | border: 1px solid #e2e2e2; 180 | border-radius: 4px; 181 | overflow-x: auto; } 182 | 183 | .declaration .highlight { 184 | overflow-x: initial; 185 | padding: 0 40px 40px 0; 186 | margin-bottom: -25px; 187 | background-color: transparent; 188 | border: none; } 189 | 190 | .section-name { 191 | margin: 0; 192 | margin-left: 18px; } 193 | 194 | .task-group-section { 195 | padding-left: 6px; 196 | border-top: 1px solid #e2e2e2; } 197 | 198 | .task-group { 199 | padding-top: 0px; } 200 | 201 | .task-name-container a[name]:before { 202 | content: ""; 203 | display: block; 204 | padding-top: 70px; 205 | margin: -70px 0 0; } 206 | 207 | .item { 208 | padding-top: 8px; 209 | width: 100%; 210 | list-style-type: none; } 211 | .item a[name]:before { 212 | content: ""; 213 | display: block; 214 | padding-top: 70px; 215 | margin: -70px 0 0; } 216 | .item code { 217 | background-color: transparent; 218 | padding: 0; } 219 | .item .token { 220 | padding-left: 3px; 221 | margin-left: 15px; 222 | font-size: 11.9px; } 223 | .item .declaration-note { 224 | font-size: .85em; 225 | color: gray; 226 | font-style: italic; } 227 | 228 | .pointer-container { 229 | border-bottom: 1px solid #e2e2e2; 230 | left: -23px; 231 | padding-bottom: 13px; 232 | position: relative; 233 | width: 110%; } 234 | 235 | .pointer { 236 | background: #f9f9f9; 237 | border-left: 1px solid #e2e2e2; 238 | border-top: 1px solid #e2e2e2; 239 | height: 12px; 240 | left: 21px; 241 | top: -7px; 242 | -webkit-transform: rotate(45deg); 243 | -moz-transform: rotate(45deg); 244 | -o-transform: rotate(45deg); 245 | transform: rotate(45deg); 246 | position: absolute; 247 | width: 12px; } 248 | 249 | .height-container { 250 | display: none; 251 | left: -25px; 252 | padding: 0 25px; 253 | position: relative; 254 | width: 100%; 255 | overflow: hidden; } 256 | .height-container .section { 257 | background: #f9f9f9; 258 | border-bottom: 1px solid #e2e2e2; 259 | left: -25px; 260 | position: relative; 261 | width: 100%; 262 | padding-top: 10px; 263 | padding-bottom: 5px; } 264 | 265 | .aside, .language { 266 | padding: 6px 12px; 267 | margin: 12px 0; 268 | border-left: 5px solid #dddddd; 269 | overflow-y: hidden; } 270 | .aside .aside-title, .language .aside-title { 271 | font-size: 9px; 272 | letter-spacing: 2px; 273 | text-transform: uppercase; 274 | padding-bottom: 0; 275 | margin: 0; 276 | color: #aaa; 277 | -webkit-user-select: none; } 278 | .aside p:last-child, .language p:last-child { 279 | margin-bottom: 0; } 280 | 281 | .language { 282 | border-left: 5px solid #cde9f4; } 283 | .language .aside-title { 284 | color: #4b8afb; } 285 | 286 | .aside-warning { 287 | border-left: 5px solid #ff6666; } 288 | .aside-warning .aside-title { 289 | color: #ff0000; } 290 | 291 | .graybox { 292 | border-collapse: collapse; 293 | width: 100%; } 294 | .graybox p { 295 | margin: 0; 296 | word-break: break-word; 297 | min-width: 50px; } 298 | .graybox td { 299 | border: 1px solid #e2e2e2; 300 | padding: 5px 25px 5px 10px; 301 | vertical-align: middle; } 302 | .graybox tr td:first-of-type { 303 | text-align: right; 304 | padding: 7px; 305 | vertical-align: top; 306 | word-break: normal; 307 | width: 40px; } 308 | 309 | .slightly-smaller { 310 | font-size: 0.9em; } 311 | 312 | #footer { 313 | position: absolute; 314 | bottom: 10px; 315 | margin-left: 25px; } 316 | #footer p { 317 | margin: 0; 318 | color: #aaa; 319 | font-size: 0.8em; } 320 | 321 | html.dash header, html.dash #breadcrumbs, html.dash .sidebar { 322 | display: none; } 323 | html.dash .main-content { 324 | width: 980px; 325 | margin-left: 0; 326 | border: none; 327 | width: 100%; 328 | top: 0; 329 | padding-bottom: 0; } 330 | html.dash .height-container { 331 | display: block; } 332 | html.dash .item .token { 333 | margin-left: 0; } 334 | html.dash .content-wrapper { 335 | width: auto; } 336 | html.dash #footer { 337 | position: static; } 338 | -------------------------------------------------------------------------------- /docs/docsets/Doric.docset/Contents/Resources/Documents/img/carat.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jayeshk/Doric/2629fb2d1328fdbf7d76a8583e3931caa8238168/docs/docsets/Doric.docset/Contents/Resources/Documents/img/carat.png -------------------------------------------------------------------------------- /docs/docsets/Doric.docset/Contents/Resources/Documents/img/dash.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jayeshk/Doric/2629fb2d1328fdbf7d76a8583e3931caa8238168/docs/docsets/Doric.docset/Contents/Resources/Documents/img/dash.png -------------------------------------------------------------------------------- /docs/docsets/Doric.docset/Contents/Resources/Documents/img/gh.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jayeshk/Doric/2629fb2d1328fdbf7d76a8583e3931caa8238168/docs/docsets/Doric.docset/Contents/Resources/Documents/img/gh.png -------------------------------------------------------------------------------- /docs/docsets/Doric.docset/Contents/Resources/Documents/js/jazzy.js: -------------------------------------------------------------------------------- 1 | window.jazzy = {'docset': false} 2 | if (typeof window.dash != 'undefined') { 3 | document.documentElement.className += ' dash' 4 | window.jazzy.docset = true 5 | } 6 | if (navigator.userAgent.match(/xcode/i)) { 7 | document.documentElement.className += ' xcode' 8 | window.jazzy.docset = true 9 | } 10 | 11 | // On doc load, toggle the URL hash discussion if present 12 | $(document).ready(function() { 13 | if (!window.jazzy.docset) { 14 | var linkToHash = $('a[href="' + window.location.hash +'"]'); 15 | linkToHash.trigger("click"); 16 | } 17 | }); 18 | 19 | // On token click, toggle its discussion and animate token.marginLeft 20 | $(".token").click(function(event) { 21 | if (window.jazzy.docset) { 22 | return; 23 | } 24 | var link = $(this); 25 | var animationDuration = 300; 26 | var tokenOffset = "15px"; 27 | var original = link.css('marginLeft') == tokenOffset; 28 | link.animate({'margin-left':original ? "0px" : tokenOffset}, animationDuration); 29 | $content = link.parent().parent().next(); 30 | $content.slideToggle(animationDuration); 31 | 32 | // Keeps the document from jumping to the hash. 33 | var href = $(this).attr('href'); 34 | if (history.pushState) { 35 | history.pushState({}, '', href); 36 | } else { 37 | location.hash = href; 38 | } 39 | event.preventDefault(); 40 | }); 41 | 42 | // Dumb down quotes within code blocks that delimit strings instead of quotations 43 | // https://github.com/realm/jazzy/issues/714 44 | $("code q").replaceWith(function () { 45 | return ["\"", $(this).contents(), "\""]; 46 | }); 47 | -------------------------------------------------------------------------------- /docs/docsets/Doric.docset/Contents/Resources/docSet.dsidx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jayeshk/Doric/2629fb2d1328fdbf7d76a8583e3931caa8238168/docs/docsets/Doric.docset/Contents/Resources/docSet.dsidx -------------------------------------------------------------------------------- /docs/docsets/Doric.tgz: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jayeshk/Doric/2629fb2d1328fdbf7d76a8583e3931caa8238168/docs/docsets/Doric.tgz -------------------------------------------------------------------------------- /docs/docsets/Doric.xml: -------------------------------------------------------------------------------- 1 | 1.0.0https://github.com/jayeshk/Doric/docsets/Doric.tgz 2 | -------------------------------------------------------------------------------- /docs/img/carat.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jayeshk/Doric/2629fb2d1328fdbf7d76a8583e3931caa8238168/docs/img/carat.png -------------------------------------------------------------------------------- /docs/img/dash.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jayeshk/Doric/2629fb2d1328fdbf7d76a8583e3931caa8238168/docs/img/dash.png -------------------------------------------------------------------------------- /docs/img/gh.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jayeshk/Doric/2629fb2d1328fdbf7d76a8583e3931caa8238168/docs/img/gh.png -------------------------------------------------------------------------------- /docs/js/jazzy.js: -------------------------------------------------------------------------------- 1 | window.jazzy = {'docset': false} 2 | if (typeof window.dash != 'undefined') { 3 | document.documentElement.className += ' dash' 4 | window.jazzy.docset = true 5 | } 6 | if (navigator.userAgent.match(/xcode/i)) { 7 | document.documentElement.className += ' xcode' 8 | window.jazzy.docset = true 9 | } 10 | 11 | // On doc load, toggle the URL hash discussion if present 12 | $(document).ready(function() { 13 | if (!window.jazzy.docset) { 14 | var linkToHash = $('a[href="' + window.location.hash +'"]'); 15 | linkToHash.trigger("click"); 16 | } 17 | }); 18 | 19 | // On token click, toggle its discussion and animate token.marginLeft 20 | $(".token").click(function(event) { 21 | if (window.jazzy.docset) { 22 | return; 23 | } 24 | var link = $(this); 25 | var animationDuration = 300; 26 | var tokenOffset = "15px"; 27 | var original = link.css('marginLeft') == tokenOffset; 28 | link.animate({'margin-left':original ? "0px" : tokenOffset}, animationDuration); 29 | $content = link.parent().parent().next(); 30 | $content.slideToggle(animationDuration); 31 | 32 | // Keeps the document from jumping to the hash. 33 | var href = $(this).attr('href'); 34 | if (history.pushState) { 35 | history.pushState({}, '', href); 36 | } else { 37 | location.hash = href; 38 | } 39 | event.preventDefault(); 40 | }); 41 | 42 | // Dumb down quotes within code blocks that delimit strings instead of quotations 43 | // https://github.com/realm/jazzy/issues/714 44 | $("code q").replaceWith(function () { 45 | return ["\"", $(this).contents(), "\""]; 46 | }); 47 | -------------------------------------------------------------------------------- /doric.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jayeshk/Doric/2629fb2d1328fdbf7d76a8583e3931caa8238168/doric.png -------------------------------------------------------------------------------- /screens-preview.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jayeshk/Doric/2629fb2d1328fdbf7d76a8583e3931caa8238168/screens-preview.gif --------------------------------------------------------------------------------