├── .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 | 
4 |
5 | [](https://travis-ci.com/jayeshk/Doric) [](https://img.shields.io/cocoapods/v/Doric.svg) [](https://github.com/Carthage/Carthage) [](https://github.com/jayeshk/Doric)
6 | 
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 |  
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 |
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 |
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
--------------------------------------------------------------------------------