├── .gitattributes
├── Demos
├── .DS_Store
├── FAB.framer
│ ├── .gitignore
│ ├── app.coffee
│ ├── framer
│ │ ├── .bookmark
│ │ ├── coffee-script.js
│ │ ├── config.json
│ │ ├── design.vekter
│ │ ├── framer.generated.js
│ │ ├── framer.init.js
│ │ ├── framer.js
│ │ ├── framer.js.map
│ │ ├── framer.modules.js
│ │ ├── framer.vekter.js
│ │ ├── images
│ │ │ ├── cursor-active.png
│ │ │ ├── cursor-active@2x.png
│ │ │ ├── cursor.png
│ │ │ ├── cursor@2x.png
│ │ │ ├── icon-120.png
│ │ │ ├── icon-152.png
│ │ │ ├── icon-180.png
│ │ │ ├── icon-192.png
│ │ │ └── icon-76.png
│ │ ├── style.css
│ │ └── version
│ ├── images
│ │ └── .gitkeep
│ ├── index.html
│ └── modules
│ │ └── MaterialComponents.coffee
├── Form.framer
│ ├── .gitignore
│ ├── app.coffee
│ ├── framer
│ │ ├── .bookmark
│ │ ├── coffee-script.js
│ │ ├── config.json
│ │ ├── design.vekter
│ │ ├── framer.generated.js
│ │ ├── framer.init.js
│ │ ├── framer.js
│ │ ├── framer.js.map
│ │ ├── framer.modules.js
│ │ ├── framer.vekter.js
│ │ ├── images
│ │ │ ├── cursor-active.png
│ │ │ ├── cursor-active@2x.png
│ │ │ ├── cursor.png
│ │ │ ├── cursor@2x.png
│ │ │ ├── icon-120.png
│ │ │ ├── icon-152.png
│ │ │ ├── icon-180.png
│ │ │ ├── icon-192.png
│ │ │ └── icon-76.png
│ │ ├── style.css
│ │ └── version
│ ├── images
│ │ └── .gitkeep
│ ├── index.html
│ └── modules
│ │ └── MaterialComponents.coffee
└── Register.framer
│ ├── .gitignore
│ ├── app.coffee
│ ├── framer
│ ├── .bookmark
│ ├── coffee-script.js
│ ├── config.json
│ ├── design.vekter
│ ├── framer.generated.js
│ ├── framer.init.js
│ ├── framer.js
│ ├── framer.js.map
│ ├── framer.modules.js
│ ├── framer.vekter.js
│ ├── images
│ │ ├── cursor-active.png
│ │ ├── cursor-active@2x.png
│ │ ├── cursor.png
│ │ ├── cursor@2x.png
│ │ ├── icon-120.png
│ │ ├── icon-152.png
│ │ ├── icon-180.png
│ │ ├── icon-192.png
│ │ └── icon-76.png
│ ├── style.css
│ └── version
│ ├── images
│ └── .gitkeep
│ ├── index.html
│ └── modules
│ └── MaterialComponents.coffee
├── MaterialComponents.coffee
└── README.md
/.gitattributes:
--------------------------------------------------------------------------------
1 | # Auto detect text files and perform LF normalization
2 | * text=auto
--------------------------------------------------------------------------------
/Demos/.DS_Store:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/TessGadd/MaterialComponents/fdd414a35ce5415a2c372e1a3c29783c34ca0005/Demos/.DS_Store
--------------------------------------------------------------------------------
/Demos/FAB.framer/.gitignore:
--------------------------------------------------------------------------------
1 | # Framer Git Ignore
2 |
3 | # General OSX
4 |
5 | .DS_Store
6 | .AppleDouble
7 | .LSOverride
8 |
9 | # Icon must end with two \r
10 | Icon
11 |
12 | # Thumbnails
13 | ._*
14 |
15 | # Files that might appear in the root of a volume
16 | .DocumentRevisions-V100
17 | .fseventsd
18 | .Spotlight-V100
19 | .TemporaryItems
20 | .Trashes
21 | .VolumeIcon.icns
22 |
23 | # Directories potentially created on remote AFP share
24 | .AppleDB
25 | .AppleDesktop
26 | Network Trash Folder
27 | Temporary Items
28 | .apdisk
29 |
30 | # Framer Specific
31 | .*.html
32 | .app.js
33 | framer/*.old*
34 | framer/.*.hash
35 | framer/backup.coffee
36 | framer/backups/*
37 | framer/manifest.txt
38 | framer/preview.png
39 | framer/social-*x*.png
40 |
--------------------------------------------------------------------------------
/Demos/FAB.framer/app.coffee:
--------------------------------------------------------------------------------
1 | MaterialComponents = require 'MaterialComponents'
2 |
3 | bg = new BackgroundLayer
4 | backgroundColor: MaterialComponents.white
5 |
6 | header = new MaterialComponents.AppBar
7 | mobile: true
8 | themeColor: MaterialComponents.purple
9 | menuIconY: Align.center(-5)
10 | statusIconsY: Align.center(-3)
11 |
12 | fab = new MaterialComponents.FAB
13 | themeColor: MaterialComponents.purple
14 | icon: "share"
15 |
--------------------------------------------------------------------------------
/Demos/FAB.framer/framer/.bookmark:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/TessGadd/MaterialComponents/fdd414a35ce5415a2c372e1a3c29783c34ca0005/Demos/FAB.framer/framer/.bookmark
--------------------------------------------------------------------------------
/Demos/FAB.framer/framer/config.json:
--------------------------------------------------------------------------------
1 | {
2 | "orientation" : 0,
3 | "updateDelay" : 0.3,
4 | "designModeSelected" : 0,
5 | "cachedDeviceHeight" : 640,
6 | "contentScale" : 1,
7 | "cachedDeviceWidth" : 384,
8 | "fullScreen" : false,
9 | "deviceType" : "google-nexus-4",
10 | "sharedPrototype" : 0,
11 | "propertyPanelToggleStates" : {
12 |
13 | },
14 | "projectId" : "5CB87C70-76A7-48D0-AA4D-EF7B002CD5ED",
15 | "deviceOrientation" : 0,
16 | "selectedHand" : "",
17 | "showBezel" : false,
18 | "foldedCodeRanges" : [
19 |
20 | ],
21 | "deviceScale" : "fit"
22 | }
--------------------------------------------------------------------------------
/Demos/FAB.framer/framer/design.vekter:
--------------------------------------------------------------------------------
1 | {
2 | "version" : 12,
3 | "root" : {
4 | "id" : "F@zUO{bk",
5 | "__class" : "CanvasNode",
6 | "parentid" : null,
7 | "children" : [
8 |
9 | ]
10 | }
11 | }
--------------------------------------------------------------------------------
/Demos/FAB.framer/framer/framer.generated.js:
--------------------------------------------------------------------------------
1 | // This is autogenerated by Framer
2 |
3 |
4 | if (!window.Framer && window._bridge) {window._bridge('runtime.error', {message:'[framer.js] Framer library missing or corrupt. Select File → Update Framer Library.'})}
5 | if (DeviceComponent) {DeviceComponent.Devices["iphone-6-silver"].deviceImageJP2 = false};
6 | if (window.Framer) {window.Framer.Defaults.DeviceView = {"deviceScale":"fit","selectedHand":"","deviceType":"google-nexus-4","contentScale":1,"hideBezel":true,"orientation":0};
7 | }
8 | if (window.Framer) {window.Framer.Defaults.DeviceComponent = {"deviceScale":"fit","selectedHand":"","deviceType":"google-nexus-4","contentScale":1,"hideBezel":true,"orientation":0};
9 | }
10 | window.FramerStudioInfo = {"deviceImagesUrl":"\/_server\/resources\/DeviceImages","documentTitle":"FAB.framer"};
11 |
12 | Framer.Device = new Framer.DeviceView();
13 | Framer.Device.setupContext();
--------------------------------------------------------------------------------
/Demos/FAB.framer/framer/framer.init.js:
--------------------------------------------------------------------------------
1 | (function() {
2 |
3 | function isFileLoadingAllowed() {
4 | return (window.location.protocol.indexOf("file") == -1)
5 | }
6 |
7 | function isHomeScreened() {
8 | return ("standalone" in window.navigator) && window.navigator.standalone == true
9 | }
10 |
11 | function isCompatibleBrowser() {
12 | return Utils.isWebKit()
13 | }
14 |
15 | var alertNode;
16 |
17 | function dismissAlert() {
18 | alertNode.parentElement.removeChild(alertNode)
19 | loadProject()
20 | }
21 |
22 | function showAlert(html) {
23 |
24 | alertNode = document.createElement("div")
25 |
26 | alertNode.classList.add("framerAlertBackground")
27 | alertNode.innerHTML = html
28 |
29 | document.addEventListener("DOMContentLoaded", function(event) {
30 | document.body.appendChild(alertNode)
31 | })
32 |
33 | window.dismissAlert = dismissAlert;
34 | }
35 |
36 | function showBrowserAlert() {
37 | var html = ""
38 | html += "
"
39 | html += "
Error: Not A WebKit Browser "
40 | html += "Your browser is not supported.
Please use Safari or Chrome.
"
41 | html += "
Try anyway "
42 | html += "
"
43 |
44 | showAlert(html)
45 | }
46 |
47 | function showFileLoadingAlert() {
48 | var html = ""
49 | html += ""
50 | html += "
Error: Local File Restrictions "
51 | html += "Preview this prototype with Framer Mirror or learn more about "
52 | html += "
file restrictions .
"
53 | html += "
Try anyway "
54 | html += "
"
55 |
56 | showAlert(html)
57 | }
58 |
59 | function loadProject(callback) {
60 | CoffeeScript.load("app.coffee", callback)
61 | }
62 |
63 | function setDefaultPageTitle() {
64 | // If no title was set we set it to the project folder name so
65 | // you get a nice name on iOS if you bookmark to desktop.
66 | document.addEventListener("DOMContentLoaded", function() {
67 | if (document.title == "") {
68 | if (window.FramerStudioInfo && window.FramerStudioInfo.documentTitle) {
69 | document.title = window.FramerStudioInfo.documentTitle
70 | } else {
71 | document.title = window.location.pathname.replace(/\//g, "")
72 | }
73 | }
74 | })
75 | }
76 |
77 | function init() {
78 |
79 | if (Utils.isFramerStudio()) {
80 | return
81 | }
82 |
83 | setDefaultPageTitle()
84 |
85 | if (!isCompatibleBrowser()) {
86 | return showBrowserAlert()
87 | }
88 |
89 | if (!isFileLoadingAllowed()) {
90 | return showFileLoadingAlert()
91 | }
92 |
93 | loadProject(function(){
94 | // CoffeeScript: Framer?.CurrentContext?.emit?("loaded:project")
95 | var context;
96 | if (typeof Framer !== "undefined" && Framer !== null) {
97 | if ((context = Framer.CurrentContext) != null) {
98 | if (typeof context.emit === "function") {
99 | context.emit("loaded:project");
100 | }
101 | }
102 | }
103 | })
104 | }
105 |
106 | init()
107 |
108 | })()
109 |
--------------------------------------------------------------------------------
/Demos/FAB.framer/framer/framer.vekter.js:
--------------------------------------------------------------------------------
1 | (function(scope) {if (scope["__vekterVariables"]) { scope["__vekterVariables"].map(function(variable) { delete scope[variable] } ) };Object.assign(scope, {});scope["__vekterVariables"] = [""];if (typeof Framer.CurrentContext.layout === 'function') {Framer.CurrentContext.layout()};})(window);
--------------------------------------------------------------------------------
/Demos/FAB.framer/framer/images/cursor-active.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/TessGadd/MaterialComponents/fdd414a35ce5415a2c372e1a3c29783c34ca0005/Demos/FAB.framer/framer/images/cursor-active.png
--------------------------------------------------------------------------------
/Demos/FAB.framer/framer/images/cursor-active@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/TessGadd/MaterialComponents/fdd414a35ce5415a2c372e1a3c29783c34ca0005/Demos/FAB.framer/framer/images/cursor-active@2x.png
--------------------------------------------------------------------------------
/Demos/FAB.framer/framer/images/cursor.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/TessGadd/MaterialComponents/fdd414a35ce5415a2c372e1a3c29783c34ca0005/Demos/FAB.framer/framer/images/cursor.png
--------------------------------------------------------------------------------
/Demos/FAB.framer/framer/images/cursor@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/TessGadd/MaterialComponents/fdd414a35ce5415a2c372e1a3c29783c34ca0005/Demos/FAB.framer/framer/images/cursor@2x.png
--------------------------------------------------------------------------------
/Demos/FAB.framer/framer/images/icon-120.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/TessGadd/MaterialComponents/fdd414a35ce5415a2c372e1a3c29783c34ca0005/Demos/FAB.framer/framer/images/icon-120.png
--------------------------------------------------------------------------------
/Demos/FAB.framer/framer/images/icon-152.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/TessGadd/MaterialComponents/fdd414a35ce5415a2c372e1a3c29783c34ca0005/Demos/FAB.framer/framer/images/icon-152.png
--------------------------------------------------------------------------------
/Demos/FAB.framer/framer/images/icon-180.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/TessGadd/MaterialComponents/fdd414a35ce5415a2c372e1a3c29783c34ca0005/Demos/FAB.framer/framer/images/icon-180.png
--------------------------------------------------------------------------------
/Demos/FAB.framer/framer/images/icon-192.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/TessGadd/MaterialComponents/fdd414a35ce5415a2c372e1a3c29783c34ca0005/Demos/FAB.framer/framer/images/icon-192.png
--------------------------------------------------------------------------------
/Demos/FAB.framer/framer/images/icon-76.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/TessGadd/MaterialComponents/fdd414a35ce5415a2c372e1a3c29783c34ca0005/Demos/FAB.framer/framer/images/icon-76.png
--------------------------------------------------------------------------------
/Demos/FAB.framer/framer/style.css:
--------------------------------------------------------------------------------
1 | * {
2 | margin: 0;
3 | padding: 0;
4 | border: none;
5 | -webkit-user-select: none;
6 | -webkit-tap-highlight-color: rgba(0,0,0,0);
7 | }
8 |
9 | body {
10 | background-color: #fff;
11 | font: 28px/1em "Helvetica";
12 | color: gray;
13 | overflow: hidden;
14 | }
15 |
16 | a {
17 | color: gray;
18 | }
19 |
20 | body {
21 | cursor: url('images/cursor.png') 32 32, auto;
22 | cursor: -webkit-image-set(
23 | url('images/cursor.png') 1x,
24 | url('images/cursor@2x.png') 2x
25 | ) 32 32, auto;
26 | }
27 |
28 | body:active {
29 | cursor: url('images/cursor-active.png') 32 32, auto;
30 | cursor: -webkit-image-set(
31 | url('images/cursor-active.png') 1x,
32 | url('images/cursor-active@2x.png') 2x
33 | ) 32 32, auto;
34 | }
35 |
36 | .framerAlertBackground {
37 | position: absolute; top:0px; left:0px; right:0px; bottom:0px;
38 | z-index: 1000;
39 | background-color: #fff;
40 | }
41 |
42 | .framerAlert {
43 | font:400 14px/1.4 "Helvetica Neue", Helvetica, Arial, sans-serif;
44 | -webkit-font-smoothing:antialiased;
45 | color:#616367; text-align:center;
46 | position: absolute; top:40%; left:50%; width:260px; margin-left:-130px;
47 | }
48 | .framerAlert strong { font-weight:500; color:#000; margin-bottom:8px; display:block; }
49 | .framerAlert a { color:#28AFFA; }
50 | .framerAlert .btn {
51 | font-weight:500; text-decoration:none; line-height:1;
52 | display:inline-block; padding:6px 12px 7px 12px;
53 | border-radius:3px; margin-top:12px;
54 | background:#28AFFA; color:#fff;
55 | }
56 |
57 | ::-webkit-scrollbar {
58 | display: none;
59 | }
--------------------------------------------------------------------------------
/Demos/FAB.framer/framer/version:
--------------------------------------------------------------------------------
1 | 10
--------------------------------------------------------------------------------
/Demos/FAB.framer/images/.gitkeep:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/TessGadd/MaterialComponents/fdd414a35ce5415a2c372e1a3c29783c34ca0005/Demos/FAB.framer/images/.gitkeep
--------------------------------------------------------------------------------
/Demos/FAB.framer/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
--------------------------------------------------------------------------------
/Demos/Form.framer/.gitignore:
--------------------------------------------------------------------------------
1 | # Framer Git Ignore
2 |
3 | # General OSX
4 |
5 | .DS_Store
6 | .AppleDouble
7 | .LSOverride
8 |
9 | # Icon must end with two \r
10 | Icon
11 |
12 | # Thumbnails
13 | ._*
14 |
15 | # Files that might appear in the root of a volume
16 | .DocumentRevisions-V100
17 | .fseventsd
18 | .Spotlight-V100
19 | .TemporaryItems
20 | .Trashes
21 | .VolumeIcon.icns
22 |
23 | # Directories potentially created on remote AFP share
24 | .AppleDB
25 | .AppleDesktop
26 | Network Trash Folder
27 | Temporary Items
28 | .apdisk
29 |
30 | # Framer Specific
31 | .*.html
32 | .app.js
33 | framer/*.old*
34 | framer/.*.hash
35 | framer/backup.coffee
36 | framer/backups/*
37 | framer/manifest.txt
38 | framer/preview.png
39 | framer/social-*x*.png
40 |
--------------------------------------------------------------------------------
/Demos/Form.framer/app.coffee:
--------------------------------------------------------------------------------
1 | MaterialComponents = require 'MaterialComponents'
2 |
3 | padding = 32
4 |
5 |
6 |
7 | scroll = new ScrollComponent
8 | width: Screen.width
9 | height: Screen.height
10 | backgroundColor: "#fff"
11 | scrollHorizontal: false
12 |
13 | head = new MaterialComponents.AppBar
14 | themeColor: MaterialComponents.indigo
15 | labelText: "Survey"
16 | mobile: true
17 | statusIconsY: Align.center()
18 | menuIconY: Align.center(-1)
19 |
20 | field1 = new MaterialComponents.TextField_Basic
21 | x: padding
22 | y: padding + head.height
23 | width: 300
24 | labelText: "Name"
25 | themeColor: MaterialComponents.indigo
26 | parent: scroll.content
27 |
28 | field2 = new MaterialComponents.RadioButtons
29 | x: padding
30 | y: padding + field1.height + field1.y
31 | width: 300
32 | labelText: "Did you like the event?"
33 | themeColor: MaterialComponents.indigo
34 | type: "password"
35 | choices: ["yes", "it was 'ok'", "no"]
36 | parent: scroll.content
37 |
38 |
39 | field3 = new MaterialComponents.Checkboxes
40 | x: padding
41 | y: padding + field2.height + field2.y
42 | width: 300
43 | labelText: "What did you like"
44 | themeColor: MaterialComponents.indigo
45 | type: "password"
46 | parent: scroll.content
47 | choices: ["the bar", "pony rides", "jumping castles", "music"]
48 | checkY: 4
49 |
50 | field4 = new MaterialComponents.TextArea
51 | x: padding
52 | y: padding + field3.height + field3.y
53 | width: 300
54 | labelText: "Comments"
55 | themeColor: MaterialComponents.indigo
56 | parent: scroll.content
57 |
58 | button = new MaterialComponents.RaisedButton
59 | x: padding
60 | y: padding + field4.height + field4.y
61 | labelText: "Submit"
62 | themeColor: MaterialComponents.indigo
63 | parent: scroll.content
--------------------------------------------------------------------------------
/Demos/Form.framer/framer/.bookmark:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/TessGadd/MaterialComponents/fdd414a35ce5415a2c372e1a3c29783c34ca0005/Demos/Form.framer/framer/.bookmark
--------------------------------------------------------------------------------
/Demos/Form.framer/framer/config.json:
--------------------------------------------------------------------------------
1 | {
2 | "orientation" : 0,
3 | "updateDelay" : 0.3,
4 | "designModeSelected" : 0,
5 | "cachedDeviceHeight" : 731.4285888671875,
6 | "contentScale" : 1,
7 | "cachedDeviceWidth" : 411.4285583496094,
8 | "fullScreen" : false,
9 | "deviceType" : "google-nexus-6p",
10 | "sharedPrototype" : true,
11 | "propertyPanelToggleStates" : {
12 |
13 | },
14 | "projectId" : "77F04927-B690-49DA-AD90-15927740D705",
15 | "deviceOrientation" : 0,
16 | "selectedHand" : "",
17 | "showBezel" : 0,
18 | "foldedCodeRanges" : [
19 |
20 | ],
21 | "deviceScale" : "fit"
22 | }
--------------------------------------------------------------------------------
/Demos/Form.framer/framer/design.vekter:
--------------------------------------------------------------------------------
1 | {
2 | "version" : 12,
3 | "root" : {
4 | "id" : "F@zUO{bk",
5 | "__class" : "CanvasNode",
6 | "parentid" : null,
7 | "children" : [
8 |
9 | ]
10 | }
11 | }
--------------------------------------------------------------------------------
/Demos/Form.framer/framer/framer.generated.js:
--------------------------------------------------------------------------------
1 | // This is autogenerated by Framer
2 |
3 |
4 | if (!window.Framer && window._bridge) {window._bridge('runtime.error', {message:'[framer.js] Framer library missing or corrupt. Select File → Update Framer Library.'})}
5 | if (DeviceComponent) {DeviceComponent.Devices["iphone-6-silver"].deviceImageJP2 = false};
6 | if (window.Framer) {window.Framer.Defaults.DeviceView = {"deviceScale":"fit","selectedHand":"","deviceType":"google-nexus-6p","contentScale":1,"hideBezel":true,"orientation":0};
7 | }
8 | if (window.Framer) {window.Framer.Defaults.DeviceComponent = {"deviceScale":"fit","selectedHand":"","deviceType":"google-nexus-6p","contentScale":1,"hideBezel":true,"orientation":0};
9 | }
10 | window.FramerStudioInfo = {"deviceImagesUrl":"\/_server\/resources\/DeviceImages","documentTitle":"Form.framer"};
11 |
12 | Framer.Device = new Framer.DeviceView();
13 | Framer.Device.setupContext();
--------------------------------------------------------------------------------
/Demos/Form.framer/framer/framer.init.js:
--------------------------------------------------------------------------------
1 | (function() {
2 |
3 | function isFileLoadingAllowed() {
4 | return (window.location.protocol.indexOf("file") == -1)
5 | }
6 |
7 | function isHomeScreened() {
8 | return ("standalone" in window.navigator) && window.navigator.standalone == true
9 | }
10 |
11 | function isCompatibleBrowser() {
12 | return Utils.isWebKit()
13 | }
14 |
15 | var alertNode;
16 |
17 | function dismissAlert() {
18 | alertNode.parentElement.removeChild(alertNode)
19 | loadProject()
20 | }
21 |
22 | function showAlert(html) {
23 |
24 | alertNode = document.createElement("div")
25 |
26 | alertNode.classList.add("framerAlertBackground")
27 | alertNode.innerHTML = html
28 |
29 | document.addEventListener("DOMContentLoaded", function(event) {
30 | document.body.appendChild(alertNode)
31 | })
32 |
33 | window.dismissAlert = dismissAlert;
34 | }
35 |
36 | function showBrowserAlert() {
37 | var html = ""
38 | html += ""
39 | html += "
Error: Not A WebKit Browser "
40 | html += "Your browser is not supported.
Please use Safari or Chrome.
"
41 | html += "
Try anyway "
42 | html += "
"
43 |
44 | showAlert(html)
45 | }
46 |
47 | function showFileLoadingAlert() {
48 | var html = ""
49 | html += ""
50 | html += "
Error: Local File Restrictions "
51 | html += "Preview this prototype with Framer Mirror or learn more about "
52 | html += "
file restrictions .
"
53 | html += "
Try anyway "
54 | html += "
"
55 |
56 | showAlert(html)
57 | }
58 |
59 | function loadProject(callback) {
60 | CoffeeScript.load("app.coffee", callback)
61 | }
62 |
63 | function setDefaultPageTitle() {
64 | // If no title was set we set it to the project folder name so
65 | // you get a nice name on iOS if you bookmark to desktop.
66 | document.addEventListener("DOMContentLoaded", function() {
67 | if (document.title == "") {
68 | if (window.FramerStudioInfo && window.FramerStudioInfo.documentTitle) {
69 | document.title = window.FramerStudioInfo.documentTitle
70 | } else {
71 | document.title = window.location.pathname.replace(/\//g, "")
72 | }
73 | }
74 | })
75 | }
76 |
77 | function init() {
78 |
79 | if (Utils.isFramerStudio()) {
80 | return
81 | }
82 |
83 | setDefaultPageTitle()
84 |
85 | if (!isCompatibleBrowser()) {
86 | return showBrowserAlert()
87 | }
88 |
89 | if (!isFileLoadingAllowed()) {
90 | return showFileLoadingAlert()
91 | }
92 |
93 | loadProject(function(){
94 | // CoffeeScript: Framer?.CurrentContext?.emit?("loaded:project")
95 | var context;
96 | if (typeof Framer !== "undefined" && Framer !== null) {
97 | if ((context = Framer.CurrentContext) != null) {
98 | if (typeof context.emit === "function") {
99 | context.emit("loaded:project");
100 | }
101 | }
102 | }
103 | })
104 | }
105 |
106 | init()
107 |
108 | })()
109 |
--------------------------------------------------------------------------------
/Demos/Form.framer/framer/framer.vekter.js:
--------------------------------------------------------------------------------
1 | (function(scope) {if (scope["__vekterVariables"]) { scope["__vekterVariables"].map(function(variable) { delete scope[variable] } ) };Object.assign(scope, {});scope["__vekterVariables"] = [""];if (typeof Framer.CurrentContext.layout === 'function') {Framer.CurrentContext.layout()};})(window);
--------------------------------------------------------------------------------
/Demos/Form.framer/framer/images/cursor-active.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/TessGadd/MaterialComponents/fdd414a35ce5415a2c372e1a3c29783c34ca0005/Demos/Form.framer/framer/images/cursor-active.png
--------------------------------------------------------------------------------
/Demos/Form.framer/framer/images/cursor-active@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/TessGadd/MaterialComponents/fdd414a35ce5415a2c372e1a3c29783c34ca0005/Demos/Form.framer/framer/images/cursor-active@2x.png
--------------------------------------------------------------------------------
/Demos/Form.framer/framer/images/cursor.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/TessGadd/MaterialComponents/fdd414a35ce5415a2c372e1a3c29783c34ca0005/Demos/Form.framer/framer/images/cursor.png
--------------------------------------------------------------------------------
/Demos/Form.framer/framer/images/cursor@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/TessGadd/MaterialComponents/fdd414a35ce5415a2c372e1a3c29783c34ca0005/Demos/Form.framer/framer/images/cursor@2x.png
--------------------------------------------------------------------------------
/Demos/Form.framer/framer/images/icon-120.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/TessGadd/MaterialComponents/fdd414a35ce5415a2c372e1a3c29783c34ca0005/Demos/Form.framer/framer/images/icon-120.png
--------------------------------------------------------------------------------
/Demos/Form.framer/framer/images/icon-152.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/TessGadd/MaterialComponents/fdd414a35ce5415a2c372e1a3c29783c34ca0005/Demos/Form.framer/framer/images/icon-152.png
--------------------------------------------------------------------------------
/Demos/Form.framer/framer/images/icon-180.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/TessGadd/MaterialComponents/fdd414a35ce5415a2c372e1a3c29783c34ca0005/Demos/Form.framer/framer/images/icon-180.png
--------------------------------------------------------------------------------
/Demos/Form.framer/framer/images/icon-192.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/TessGadd/MaterialComponents/fdd414a35ce5415a2c372e1a3c29783c34ca0005/Demos/Form.framer/framer/images/icon-192.png
--------------------------------------------------------------------------------
/Demos/Form.framer/framer/images/icon-76.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/TessGadd/MaterialComponents/fdd414a35ce5415a2c372e1a3c29783c34ca0005/Demos/Form.framer/framer/images/icon-76.png
--------------------------------------------------------------------------------
/Demos/Form.framer/framer/style.css:
--------------------------------------------------------------------------------
1 | * {
2 | margin: 0;
3 | padding: 0;
4 | border: none;
5 | -webkit-user-select: none;
6 | -webkit-tap-highlight-color: rgba(0,0,0,0);
7 | }
8 |
9 | body {
10 | background-color: #fff;
11 | font: 28px/1em "Helvetica";
12 | color: gray;
13 | overflow: hidden;
14 | }
15 |
16 | a {
17 | color: gray;
18 | }
19 |
20 | body {
21 | cursor: url('images/cursor.png') 32 32, auto;
22 | cursor: -webkit-image-set(
23 | url('images/cursor.png') 1x,
24 | url('images/cursor@2x.png') 2x
25 | ) 32 32, auto;
26 | }
27 |
28 | body:active {
29 | cursor: url('images/cursor-active.png') 32 32, auto;
30 | cursor: -webkit-image-set(
31 | url('images/cursor-active.png') 1x,
32 | url('images/cursor-active@2x.png') 2x
33 | ) 32 32, auto;
34 | }
35 |
36 | .framerAlertBackground {
37 | position: absolute; top:0px; left:0px; right:0px; bottom:0px;
38 | z-index: 1000;
39 | background-color: #fff;
40 | }
41 |
42 | .framerAlert {
43 | font:400 14px/1.4 "Helvetica Neue", Helvetica, Arial, sans-serif;
44 | -webkit-font-smoothing:antialiased;
45 | color:#616367; text-align:center;
46 | position: absolute; top:40%; left:50%; width:260px; margin-left:-130px;
47 | }
48 | .framerAlert strong { font-weight:500; color:#000; margin-bottom:8px; display:block; }
49 | .framerAlert a { color:#28AFFA; }
50 | .framerAlert .btn {
51 | font-weight:500; text-decoration:none; line-height:1;
52 | display:inline-block; padding:6px 12px 7px 12px;
53 | border-radius:3px; margin-top:12px;
54 | background:#28AFFA; color:#fff;
55 | }
56 |
57 | ::-webkit-scrollbar {
58 | display: none;
59 | }
--------------------------------------------------------------------------------
/Demos/Form.framer/framer/version:
--------------------------------------------------------------------------------
1 | 10
--------------------------------------------------------------------------------
/Demos/Form.framer/images/.gitkeep:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/TessGadd/MaterialComponents/fdd414a35ce5415a2c372e1a3c29783c34ca0005/Demos/Form.framer/images/.gitkeep
--------------------------------------------------------------------------------
/Demos/Form.framer/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
--------------------------------------------------------------------------------
/Demos/Register.framer/.gitignore:
--------------------------------------------------------------------------------
1 | # Framer Git Ignore
2 |
3 | # General OSX
4 |
5 | .DS_Store
6 | .AppleDouble
7 | .LSOverride
8 |
9 | # Icon must end with two \r
10 | Icon
11 |
12 | # Thumbnails
13 | ._*
14 |
15 | # Files that might appear in the root of a volume
16 | .DocumentRevisions-V100
17 | .fseventsd
18 | .Spotlight-V100
19 | .TemporaryItems
20 | .Trashes
21 | .VolumeIcon.icns
22 |
23 | # Directories potentially created on remote AFP share
24 | .AppleDB
25 | .AppleDesktop
26 | Network Trash Folder
27 | Temporary Items
28 | .apdisk
29 |
30 | # Framer Specific
31 | .*.html
32 | .app.js
33 | framer/*.old*
34 | framer/.*.hash
35 | framer/backup.coffee
36 | framer/backups/*
37 | framer/manifest.txt
38 | framer/preview.png
39 | framer/social-*x*.png
40 |
--------------------------------------------------------------------------------
/Demos/Register.framer/app.coffee:
--------------------------------------------------------------------------------
1 | MaterialComponents = require 'MaterialComponents'
2 |
3 | padding = 32
4 |
5 |
6 | bg = new BackgroundLayer
7 | backgroundColor : "#fff"
8 |
9 | head = new MaterialComponents.AppBar
10 | themeColor: MaterialComponents.cyan
11 | labelText: "Sign in"
12 | mobile: true
13 | head.menuIcon.y = Align.center(-12)
14 | head.statusBar.children[1].y = Align.center(-8)
15 |
16 | field1 = new MaterialComponents.TextField_Validation
17 | x: padding
18 | y: head.height + padding
19 | labelText: "email"
20 | eyeVisible: false
21 | type: "text"
22 | width: 300
23 | match: ["joe@soap.com", "jane@doe.com", "john@smith.com"]
24 | themeColor: MaterialComponents.cyan
25 | helperText: "email address not recognised"
26 | width: Screen.width - (padding * 2)
27 |
28 |
29 | field2 = new MaterialComponents.TextField_Validation
30 | x: padding
31 | y: field1.height + padding + field1.y
32 | labelText: "password"
33 | eyeVisible: false
34 | type: "text"
35 | width: 300
36 | match: ["password123", "Fido", "alpha"]
37 | themeColor: MaterialComponents.cyan
38 | helperText: "Incorrect password"
39 | width: Screen.width - (padding * 2)
40 |
41 | button = new MaterialComponents.RaisedButton
42 | themeColor: MaterialComponents.cyan
43 | x: padding
44 | y: field2.height + padding + field2.y
--------------------------------------------------------------------------------
/Demos/Register.framer/framer/.bookmark:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/TessGadd/MaterialComponents/fdd414a35ce5415a2c372e1a3c29783c34ca0005/Demos/Register.framer/framer/.bookmark
--------------------------------------------------------------------------------
/Demos/Register.framer/framer/config.json:
--------------------------------------------------------------------------------
1 | {
2 | "orientation" : 0,
3 | "updateDelay" : 0.3,
4 | "designModeSelected" : 0,
5 | "cachedDeviceHeight" : 568,
6 | "contentScale" : 1,
7 | "cachedDeviceWidth" : 320,
8 | "fullScreen" : false,
9 | "deviceType" : "apple-iphone-5s-space-gray",
10 | "sharedPrototype" : true,
11 | "propertyPanelToggleStates" : {
12 |
13 | },
14 | "projectId" : "BF41CB30-D32C-426C-99AF-6442BC39A3C5",
15 | "deviceOrientation" : 0,
16 | "selectedHand" : "",
17 | "showBezel" : 0,
18 | "foldedCodeRanges" : [
19 |
20 | ],
21 | "deviceScale" : "fit"
22 | }
--------------------------------------------------------------------------------
/Demos/Register.framer/framer/design.vekter:
--------------------------------------------------------------------------------
1 | {
2 | "version" : 12,
3 | "root" : {
4 | "id" : "F@zUO{bk",
5 | "__class" : "CanvasNode",
6 | "parentid" : null,
7 | "children" : [
8 |
9 | ]
10 | }
11 | }
--------------------------------------------------------------------------------
/Demos/Register.framer/framer/framer.generated.js:
--------------------------------------------------------------------------------
1 | // This is autogenerated by Framer
2 |
3 |
4 | if (!window.Framer && window._bridge) {window._bridge('runtime.error', {message:'[framer.js] Framer library missing or corrupt. Select File → Update Framer Library.'})}
5 | if (DeviceComponent) {DeviceComponent.Devices["iphone-6-silver"].deviceImageJP2 = false};
6 | if (window.Framer) {window.Framer.Defaults.DeviceView = {"deviceScale":"fit","selectedHand":"","deviceType":"apple-iphone-5s-space-gray","contentScale":1,"hideBezel":true,"orientation":0};
7 | }
8 | if (window.Framer) {window.Framer.Defaults.DeviceComponent = {"deviceScale":"fit","selectedHand":"","deviceType":"apple-iphone-5s-space-gray","contentScale":1,"hideBezel":true,"orientation":0};
9 | }
10 | window.FramerStudioInfo = {"deviceImagesUrl":"\/_server\/resources\/DeviceImages","documentTitle":"Register.framer"};
11 |
12 | Framer.Device = new Framer.DeviceView();
13 | Framer.Device.setupContext();
--------------------------------------------------------------------------------
/Demos/Register.framer/framer/framer.init.js:
--------------------------------------------------------------------------------
1 | (function() {
2 |
3 | function isFileLoadingAllowed() {
4 | return (window.location.protocol.indexOf("file") == -1)
5 | }
6 |
7 | function isHomeScreened() {
8 | return ("standalone" in window.navigator) && window.navigator.standalone == true
9 | }
10 |
11 | function isCompatibleBrowser() {
12 | return Utils.isWebKit()
13 | }
14 |
15 | var alertNode;
16 |
17 | function dismissAlert() {
18 | alertNode.parentElement.removeChild(alertNode)
19 | loadProject()
20 | }
21 |
22 | function showAlert(html) {
23 |
24 | alertNode = document.createElement("div")
25 |
26 | alertNode.classList.add("framerAlertBackground")
27 | alertNode.innerHTML = html
28 |
29 | document.addEventListener("DOMContentLoaded", function(event) {
30 | document.body.appendChild(alertNode)
31 | })
32 |
33 | window.dismissAlert = dismissAlert;
34 | }
35 |
36 | function showBrowserAlert() {
37 | var html = ""
38 | html += ""
39 | html += "
Error: Not A WebKit Browser "
40 | html += "Your browser is not supported.
Please use Safari or Chrome.
"
41 | html += "
Try anyway "
42 | html += "
"
43 |
44 | showAlert(html)
45 | }
46 |
47 | function showFileLoadingAlert() {
48 | var html = ""
49 | html += ""
50 | html += "
Error: Local File Restrictions "
51 | html += "Preview this prototype with Framer Mirror or learn more about "
52 | html += "
file restrictions .
"
53 | html += "
Try anyway "
54 | html += "
"
55 |
56 | showAlert(html)
57 | }
58 |
59 | function loadProject(callback) {
60 | CoffeeScript.load("app.coffee", callback)
61 | }
62 |
63 | function setDefaultPageTitle() {
64 | // If no title was set we set it to the project folder name so
65 | // you get a nice name on iOS if you bookmark to desktop.
66 | document.addEventListener("DOMContentLoaded", function() {
67 | if (document.title == "") {
68 | if (window.FramerStudioInfo && window.FramerStudioInfo.documentTitle) {
69 | document.title = window.FramerStudioInfo.documentTitle
70 | } else {
71 | document.title = window.location.pathname.replace(/\//g, "")
72 | }
73 | }
74 | })
75 | }
76 |
77 | function init() {
78 |
79 | if (Utils.isFramerStudio()) {
80 | return
81 | }
82 |
83 | setDefaultPageTitle()
84 |
85 | if (!isCompatibleBrowser()) {
86 | return showBrowserAlert()
87 | }
88 |
89 | if (!isFileLoadingAllowed()) {
90 | return showFileLoadingAlert()
91 | }
92 |
93 | loadProject(function(){
94 | // CoffeeScript: Framer?.CurrentContext?.emit?("loaded:project")
95 | var context;
96 | if (typeof Framer !== "undefined" && Framer !== null) {
97 | if ((context = Framer.CurrentContext) != null) {
98 | if (typeof context.emit === "function") {
99 | context.emit("loaded:project");
100 | }
101 | }
102 | }
103 | })
104 | }
105 |
106 | init()
107 |
108 | })()
109 |
--------------------------------------------------------------------------------
/Demos/Register.framer/framer/framer.vekter.js:
--------------------------------------------------------------------------------
1 | (function(scope) {if (scope["__vekterVariables"]) { scope["__vekterVariables"].map(function(variable) { delete scope[variable] } ) };Object.assign(scope, {});scope["__vekterVariables"] = [""];if (typeof Framer.CurrentContext.layout === 'function') {Framer.CurrentContext.layout()};})(window);
--------------------------------------------------------------------------------
/Demos/Register.framer/framer/images/cursor-active.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/TessGadd/MaterialComponents/fdd414a35ce5415a2c372e1a3c29783c34ca0005/Demos/Register.framer/framer/images/cursor-active.png
--------------------------------------------------------------------------------
/Demos/Register.framer/framer/images/cursor-active@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/TessGadd/MaterialComponents/fdd414a35ce5415a2c372e1a3c29783c34ca0005/Demos/Register.framer/framer/images/cursor-active@2x.png
--------------------------------------------------------------------------------
/Demos/Register.framer/framer/images/cursor.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/TessGadd/MaterialComponents/fdd414a35ce5415a2c372e1a3c29783c34ca0005/Demos/Register.framer/framer/images/cursor.png
--------------------------------------------------------------------------------
/Demos/Register.framer/framer/images/cursor@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/TessGadd/MaterialComponents/fdd414a35ce5415a2c372e1a3c29783c34ca0005/Demos/Register.framer/framer/images/cursor@2x.png
--------------------------------------------------------------------------------
/Demos/Register.framer/framer/images/icon-120.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/TessGadd/MaterialComponents/fdd414a35ce5415a2c372e1a3c29783c34ca0005/Demos/Register.framer/framer/images/icon-120.png
--------------------------------------------------------------------------------
/Demos/Register.framer/framer/images/icon-152.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/TessGadd/MaterialComponents/fdd414a35ce5415a2c372e1a3c29783c34ca0005/Demos/Register.framer/framer/images/icon-152.png
--------------------------------------------------------------------------------
/Demos/Register.framer/framer/images/icon-180.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/TessGadd/MaterialComponents/fdd414a35ce5415a2c372e1a3c29783c34ca0005/Demos/Register.framer/framer/images/icon-180.png
--------------------------------------------------------------------------------
/Demos/Register.framer/framer/images/icon-192.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/TessGadd/MaterialComponents/fdd414a35ce5415a2c372e1a3c29783c34ca0005/Demos/Register.framer/framer/images/icon-192.png
--------------------------------------------------------------------------------
/Demos/Register.framer/framer/images/icon-76.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/TessGadd/MaterialComponents/fdd414a35ce5415a2c372e1a3c29783c34ca0005/Demos/Register.framer/framer/images/icon-76.png
--------------------------------------------------------------------------------
/Demos/Register.framer/framer/style.css:
--------------------------------------------------------------------------------
1 | * {
2 | margin: 0;
3 | padding: 0;
4 | border: none;
5 | -webkit-user-select: none;
6 | -webkit-tap-highlight-color: rgba(0,0,0,0);
7 | }
8 |
9 | body {
10 | background-color: #fff;
11 | font: 28px/1em "Helvetica";
12 | color: gray;
13 | overflow: hidden;
14 | }
15 |
16 | a {
17 | color: gray;
18 | }
19 |
20 | body {
21 | cursor: url('images/cursor.png') 32 32, auto;
22 | cursor: -webkit-image-set(
23 | url('images/cursor.png') 1x,
24 | url('images/cursor@2x.png') 2x
25 | ) 32 32, auto;
26 | }
27 |
28 | body:active {
29 | cursor: url('images/cursor-active.png') 32 32, auto;
30 | cursor: -webkit-image-set(
31 | url('images/cursor-active.png') 1x,
32 | url('images/cursor-active@2x.png') 2x
33 | ) 32 32, auto;
34 | }
35 |
36 | .framerAlertBackground {
37 | position: absolute; top:0px; left:0px; right:0px; bottom:0px;
38 | z-index: 1000;
39 | background-color: #fff;
40 | }
41 |
42 | .framerAlert {
43 | font:400 14px/1.4 "Helvetica Neue", Helvetica, Arial, sans-serif;
44 | -webkit-font-smoothing:antialiased;
45 | color:#616367; text-align:center;
46 | position: absolute; top:40%; left:50%; width:260px; margin-left:-130px;
47 | }
48 | .framerAlert strong { font-weight:500; color:#000; margin-bottom:8px; display:block; }
49 | .framerAlert a { color:#28AFFA; }
50 | .framerAlert .btn {
51 | font-weight:500; text-decoration:none; line-height:1;
52 | display:inline-block; padding:6px 12px 7px 12px;
53 | border-radius:3px; margin-top:12px;
54 | background:#28AFFA; color:#fff;
55 | }
56 |
57 | ::-webkit-scrollbar {
58 | display: none;
59 | }
--------------------------------------------------------------------------------
/Demos/Register.framer/framer/version:
--------------------------------------------------------------------------------
1 | 10
--------------------------------------------------------------------------------
/Demos/Register.framer/images/.gitkeep:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/TessGadd/MaterialComponents/fdd414a35ce5415a2c372e1a3c29783c34ca0005/Demos/Register.framer/images/.gitkeep
--------------------------------------------------------------------------------
/Demos/Register.framer/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
--------------------------------------------------------------------------------
/MaterialComponents.coffee:
--------------------------------------------------------------------------------
1 | ########################################################################################################
2 | # MaterialComponents version 1
3 | # Made by Tess Gadd https://medium.com/@tessgadd
4 | ########################################################################################################
5 |
6 | # This version contains
7 | # 0. global elements
8 | # 1. Color
9 | # 2. FlatButton
10 | # 3. RaisedButton
11 | # 4. FAB
12 | # 5. Checkboxes
13 | # 6. Radio Buttons
14 | # 7. Switch
15 | # 8. TextField (Text fields frankenstiend from Jordan Robert Dobson's InputField)
16 | # 9. TextField_Validation (Text fields frankenstiend from Jordan Robert Dobson's InputField)
17 | # 10. TextArea (frankenstiend from Jordan Robert Dobson's InputField and Blaine Billingsley's Autogrow)
18 | # 11. TextField_Dropdown
19 | # 12. AppBar
20 |
21 |
22 |
23 |
24 | ################################################# 0. Global Elements ################################################
25 | #---------colors
26 | label_light = "rgba(0,0,0,0.87)"
27 | label_dark = "rgba(255,255,255,1)"
28 | line_light = "rgba(0,0,0,0.54)"
29 | line_dark = "rgba(255,255,255,0.7)"
30 | input_light = "rgba(0,0,0,0.54)"
31 | input_dark = "rgba(255,255,255,1)"
32 | Inputlabel_light = box_light = "rgba(0,0,0,0.54)"
33 | Inputlabel_dark = box_dark = "rgba(255,255,255,0.7)"
34 | line_light_hover = "rgba(0,0,0,0.87)"
35 | line_dark_hover = "rgba(255,255,255,1)"
36 |
37 |
38 | #---------textlayer----------------------------------------------------------------------------------------------------
39 | class Label extends TextLayer
40 | constructor: (@options={}) ->
41 |
42 | Utils.insertCSS('@import url(https://fonts.googleapis.com/css?family=Roboto);')
43 |
44 | @options.fontFamily ?= "'Roboto', sans serif"
45 | @options.fontSize ?= 16
46 | @options.text ?= 'Label'
47 | @options.color ?= label_light
48 | @options.fontWeight ?= 400
49 | @options.letterSpacing ?= 0
50 | @options.name ?= "label"
51 |
52 | super @options
53 |
54 |
55 |
56 | #---------shadow------------------------------------------------------------------------------------------------------
57 | class Shadow extends Layer
58 | constructor: (@options={}) ->
59 |
60 | @options.backgroundColor ?= ""
61 |
62 | @umbra = new Layer
63 | width: @options.width
64 | height: @options.height
65 | backgroundColor: @options.themeColor
66 | borderRadius: @options.borderRadius
67 | shadowColor: "rgba(0,0,0,0.14)"
68 | name: "umbra"
69 |
70 | @umbra.states =
71 | _12dp:
72 | shadowY: 12
73 | shadowBlur: 17
74 | shadowSpread: 2
75 | _8dp:
76 | shadowY: 4
77 | shadowBlur: 15
78 | shadowSpread: 0
79 | _6dp:
80 | shadowY: 6
81 | shadowBlur: 10
82 | shadowSpread: 0
83 | _4dp:
84 | shadowY: 2
85 | shadowBlur: 4
86 | shadowSpread: 0
87 | _2dp:
88 | shadowY: 0
89 | shadowBlur: 2
90 | shadowSpread: 0
91 | _1dp:
92 | shadowY: 0
93 | shadowBlur: 2
94 | shadowSpread: 0
95 | _0dp:
96 | shadowY: 0
97 | shadowBlur: 0
98 | shadowSpread: 0
99 |
100 | @penumbra = new Layer
101 | width: @options.width
102 | height: @options.height
103 | backgroundColor: ""
104 | borderRadius: @options.borderRadius
105 | shadowColor: "rgba(0,0,0,0.12)"
106 | name: "penumbra"
107 |
108 | @penumbra.states =
109 | _12dp:
110 | shadowY: 5
111 | shadowBlur: 22
112 | shadowSpread: 4
113 | _8dp:
114 | shadowY: 3
115 | shadowBlur: 14
116 | shadowSpread: 3
117 | _6dp:
118 | shadowY: 1
119 | shadowBlur: 18
120 | shadowSpread: 0
121 | _4dp:
122 | shadowY: 4
123 | shadowBlur: 5
124 | shadowSpread: 0
125 | _2dp:
126 | shadowY: 2
127 | shadowBlur: 2
128 | shadowSpread: 0
129 | _1dp:
130 | shadowY: 2
131 | shadowBlur: 2
132 | shadowSpread: 0
133 | _0dp:
134 | shadowY: 0
135 | shadowBlur: 0
136 | shadowSpread: 0
137 |
138 | @ambient= new Layer
139 | width: @options.width
140 | height: @options.height
141 | backgroundColor: ""
142 | shadowColor: "rgba(0,0,0,0.20)"
143 | name: "ambient"
144 | borderRadius : @options.borderRadius
145 |
146 | @ambient.states =
147 | _12dp:
148 | shadowY: 7
149 | shadowBlur: 8
150 | shadowSpread: 0
151 | _8dp:
152 | shadowY: 8
153 | shadowBlur: 10
154 | shadowSpread: 1
155 | _6dp:
156 | shadowY: 3
157 | shadowBlur: 5
158 | shadowSpread: 0
159 | _4dp:
160 | shadowY: 1
161 | shadowBlur: 10
162 | shadowSpread: 0
163 | _2dp:
164 | shadowY: 1
165 | shadowBlur: 3
166 | shadowSpread: 0
167 | _1dp:
168 | shadowY: 1
169 | shadowBlur: 3
170 | shadowSpread: 0
171 | _0dp:
172 | shadowY: 0
173 | shadowBlur: 0
174 | shadowSpread: 0
175 |
176 | @umbra.animationOptions = time: 0.2
177 | @penumbra.animationOptions = time: 0.2
178 | @ambient.animationOptions = time: 0.2
179 |
180 | @umbra.states.switchInstant "_2dp"
181 | @penumbra.states.switchInstant "_2dp"
182 | @ambient.states.switchInstant "_2dp"
183 |
184 | super @options
185 |
186 | @umbra.parent = @
187 | @penumbra.parent = @
188 | @ambient.parent = @
189 |
190 | @array = [@umbra, @penumbra, @ambient]
191 |
192 |
193 |
194 | #--------Icons------------------------------------------------------------------------------------------------------
195 | class SystemIcon extends Layer
196 | constructor: (@options={}) ->
197 |
198 | Utils.insertCSS('@import url(https://fonts.googleapis.com/icon?family=Material+Icons); @import url(https://storage.googleapis.com/code.getmdl.io/1.0.6/material.indigo-pink.min.css); .material-icons.tab{}')
199 |
200 | @options.fontSize ?= 24
201 |
202 |
203 | @options.icon ?= "android"
204 | @options.html = "" + @options.icon + " "
205 | @options.color ?= "#009688"
206 | @options.height ?= @options.fontSize
207 | @options.width ?= @options.fontSize
208 | @options.backgroundColor = ""
209 |
210 | super @options
211 |
212 | @define 'fontSize',
213 | get: ->
214 | @options.fontSize
215 | set: (value) ->
216 | @options.fontSize = value
217 |
218 | Utils.insertCSS('@import url(https://fonts.googleapis.com/icon?family=Material+Icons); @import url(https://storage.googleapis.com/code.getmdl.io/1.0.6/material.indigo-pink.min.css); .material-icons.tab{}')
219 |
220 |
221 |
222 |
223 |
224 |
225 | ################################################# 1. Color #########################################################
226 | class exports.color extends Layer
227 | constructor: (@options={}) ->
228 | @options = _.defaults @options,
229 | super @options
230 |
231 | #reds-----------------
232 |
233 | exports.red = "#F44336"
234 | exports.red50 = "#FFEBEE"
235 | exports.red100 = "#FFCDD2"
236 | exports.red200 = "#EF9A9A"
237 | exports.red300 = "#E57373"
238 | exports.red400 = "#EF5350"
239 | exports.red500 = "#F44336"
240 | exports.red600 = "#E53935"
241 | exports.red700 = "#D32F2F"
242 | exports.red800 = "#C62828"
243 | exports.red900 = "#B71C1C"
244 | exports.redA100 = "#FF8A80"
245 | exports.redA200 = "#FF5252"
246 | exports.redA400 = "#FF1744"
247 | exports.redA700 = "#D50000"
248 |
249 | #pink-----------------
250 | exports.pink = "#E91E63"
251 | exports.pink50 = "#FCE4EC"
252 | exports.pink100 = "#F8BBD0"
253 | exports.pink200 = "#F48FB1"
254 | exports.pink300 = "#F06292"
255 | exports.pink400 = "#EC407A"
256 | exports.pink500 = "#E91E63"
257 | exports.pink600 = "#D81B60"
258 | exports.pink700 = "#C2185B"
259 | exports.pink800 = "#AD1457"
260 | exports.pink900 = "#880E4F"
261 | exports.pinkA100 = "#FF80AB"
262 | exports.pinkA200 = "#FF4081"
263 | exports.pinkA400 = "#F50057"
264 | exports.pinkA700 = "#C51162"
265 |
266 |
267 | #purple-----------------
268 | exports.purple = "#9C27B0"
269 | exports.purple50 = "#F3E5F5"
270 | exports.purple100 = "#E1BEE7"
271 | exports.purple200 = "#CE93D8"
272 | exports.purple300 = "#BA68C8"
273 | exports.purple400 = "#AB47BC"
274 | exports.purple500 = "#9C27B0"
275 | exports.purple600 = "#8E24AA"
276 | exports.purple700 = "#7B1FA2"
277 | exports.purple800 = "#6A1B9A"
278 | exports.purple900 = "#4A148C"
279 | exports.purpleA100 = "#EA80FC"
280 | exports.purpleA200 = "#E040FB"
281 | exports.purpleA400 = "#D500F9"
282 | exports.purpleA700 = "#AA00FF"
283 |
284 | #Deep purple--------------
285 | exports.deepPurple = "#673AB7"
286 | exports.deepPurple50 = "#EDE7F6"
287 | exports.deepPurple100 = "#D1C4E9"
288 | exports.deepPurple200 = "#B39DDB"
289 | exports.deepPurple300 = "#9575CD"
290 | exports.deepPurple400 = "#7E57C2"
291 | exports.deepPurple500 = "#673AB7"
292 | exports.deepPurple600 = "#5E35B1"
293 | exports.deepPurple700 = "#512DA8"
294 | exports.deepPurple800 = "#4527A0"
295 | exports.deepPurple900 = "#311B92"
296 | exports.deepPurpleA100 = "#B388FF"
297 | exports.deepPurpleA200 = "#7C4DFF"
298 | exports.deepPurpleA400 = "#651FFF"
299 | exports.deepPurpleA700 = "#6200EA"
300 | #indigo--------------
301 | exports.indigo = "#3F51B5"
302 | exports.indigo50 = "#E8EAF6"
303 | exports.indigo100 = "#C5CAE9"
304 | exports.indigo200 = "#9FA8DA"
305 | exports.indigo300 = "#7986CB"
306 | exports.indigo400 = "#5C6BC0"
307 | exports.indigo500 = "#3F51B5"
308 | exports.indigo600 = "#3949AB"
309 | exports.indigo700 = "#303F9F"
310 | exports.indigo800 = "#283593"
311 | exports.indigo900 = "#1A237E"
312 | exports.indigoA100 = "#8C9EFF"
313 | exports.indigoA200 = "#536DFE"
314 | exports.indigoA400 = "#3D5AFE"
315 | exports.indigoA700 = "#304FFE"
316 | #blue--------------
317 | exports.blue = "#2196F3"
318 | exports.blue50 = "#E3F2FD"
319 | exports.blue100 = "#BBDEFB"
320 | exports.blue200 = "#90CAF9"
321 | exports.blue300 = "#64B5F6"
322 | exports.blue400 = "#42A5F5"
323 | exports.blue500 = "#2196F3"
324 | exports.blue600 = "#1E88E5"
325 | exports.blue700 = "#1976D2"
326 | exports.blue800 = "#1565C0"
327 | exports.blue900 = "#0D47A1"
328 | exports.blueA100 = "#82B1FF"
329 | exports.blueA200 = "#448AFF"
330 | exports.blueA400 = "#2979FF"
331 | exports.blueA700 = "#2962FF"
332 | #light blue------------
333 | exports.lightBlue = "#03A9F4"
334 | exports.lightBlue50 = "#E1F5FE"
335 | exports.lightBlue100 = "#B3E5FC"
336 | exports.lightBlue200 = "#81D4FA"
337 | exports.lightBlue300 = "#4FC3F7"
338 | exports.lightBlue400 = "#29B6F6"
339 | exports.lightBlue500 = "#03A9F4"
340 | exports.lightBlue600 = "#039BE5"
341 | exports.lightBlue700 = "#0288D1"
342 | exports.lightBlue800 = "#0277BD"
343 | exports.lightBlue900 = "#01579B"
344 | exports.lightBlueA100 = "#80D8FF"
345 | exports.lightBlueA200 = "#40C4FF"
346 | exports.lightBlueA400 = "#00B0FF"
347 | exports.lightBlueA700 = "#0091EA"
348 | #cyan----------------
349 | exports.cyan = "#00BCD4"
350 | exports.cyan50 = "#E0F7FA"
351 | exports.cyan100 = "#B2EBF2"
352 | exports.cyan200 = "#80DEEA"
353 | exports.cyan300 = "#4DD0E1"
354 | exports.cyan400 = "#26C6DA"
355 | exports.cyan500 = "#00BCD4"
356 | exports.cyan600 = "#00ACC1"
357 | exports.cyan700 = "#0097A7"
358 | exports.cyan800 = "#00838F"
359 | exports.cyan900 = "#006064"
360 | exports.cyanA100 = "#84FFFF"
361 | exports.cyanA200 = "#18FFFF"
362 | exports.cyanA400 = "#00E5FF"
363 | exports.cyanA700 = "#00B8D4"
364 | #teal-------------------
365 | exports.teal = "#009688"
366 | exports.teal50 = "#E0F2F1"
367 | exports.teal100 = "#B2DFDB"
368 | exports.teal200 = "#80CBC4"
369 | exports.teal300 = "#4DB6AC"
370 | exports.teal400 = "#26A69A"
371 | exports.teal500 = "#009688"
372 | exports.teal600 = "#00897B"
373 | exports.teal700 = "#00796B"
374 | exports.teal800 = "#00695C"
375 | exports.teal900 = "#004D40"
376 | exports.tealA100 = "#A7FFEB"
377 | exports.tealA200 = "#64FFDA"
378 | exports.tealA400 = "#1DE9B6"
379 | exports.tealA700 = "#00BFA5"
380 | #green---------------
381 | exports.green = "#4CAF50"
382 | exports.green50 = "#E8F5E9"
383 | exports.green100 = "#C8E6C9"
384 | exports.green200 = "#A5D6A7"
385 | exports.green300 = "#81C784"
386 | exports.green400 = "#66BB6A"
387 | exports.green500 = "#4CAF50"
388 | exports.green600 = "#43A047"
389 | exports.green700 = "#388E3C"
390 | exports.green800 = "#2E7D32"
391 | exports.green900 = "#1B5E20"
392 | exports.greenA100 = "#B9F6CA"
393 | exports.greenA200 = "#69F0AE"
394 | exports.greenA400 = "#00E676"
395 | exports.greenA700 = "#00C853"
396 | #light green---------------
397 | exports.lightGreen = "#8BC34A"
398 | exports.lightGreen50 = "#F1F8E9"
399 | exports.lightGreen100 = "#DCEDC8"
400 | exports.lightGreen200 = "#C5E1A5"
401 | exports.lightGreen300 = "#AED581"
402 | exports.lightGreen400 = "#9CCC65"
403 | exports.lightGreen500 = "#8BC34A"
404 | exports.lightGreen600 = "#7CB342"
405 | exports.lightGreen700 = "#689F38"
406 | exports.lightGreen800 = "#558B2F"
407 | exports.lightGreen900 = "#33691E"
408 | exports.lightGreenA100 = "#CCFF90"
409 | exports.lightGreenA200 = "#B2FF59"
410 | exports.lightGreenA400 = "#76FF03"
411 | exports.lightGreenA700 = "#64DD17"
412 | #lime-----------------
413 | exports.lime = "#CDDC39"
414 | exports.lime50 = "#F9FBE7"
415 | exports.lime100 = "#F0F4C3"
416 | exports.lime200 = "#E6EE9C"
417 | exports.lime300 = "#DCE775"
418 | exports.lime400 = "#D4E157"
419 | exports.lime500 = "#CDDC39"
420 | exports.lime600 = "#C0CA33"
421 | exports.lime700 = "#AFB42B"
422 | exports.lime800 = "#9E9D24"
423 | exports.lime900 = "#827717"
424 | exports.limeA100 = "#F4FF81"
425 | exports.limeA200 = "#EEFF41"
426 | exports.limeA400 = "#C6FF00"
427 | exports.limeA700 = "#AEEA00"
428 | #yellow-----------------
429 | exports.yellow = "#FFEB3B"
430 | exports.yellow50 = "#FFFDE7"
431 | exports.yellow100 = "#FFF9C4"
432 | exports.yellow200 = "#FFF59D"
433 | exports.yellow300 = "#FFF176"
434 | exports.yellow400 = "#FFEE58"
435 | exports.yellow500 = "#FFEB3B"
436 | exports.yellow600 = "#FDD835"
437 | exports.yellow700 = "#FBC02D"
438 | exports.yellow800 = "#F9A825"
439 | exports.yellow900 = "#F57F17"
440 | exports.yellowA100 = "#FFFF8D"
441 | exports.yellowA200 = "#FFFF00"
442 | exports.yellowA400 = "#FFEA00"
443 | exports.yellowA700 = "#FFD600"
444 | #amber------------------
445 | exports.amber = "#FFC107"
446 | exports.amber50 = "#FFF8E1"
447 | exports.amber100 = "#FFECB3"
448 | exports.amber200 = "#FFE082"
449 | exports.amber300 = "#FFD54F"
450 | exports.amber400 = "#FFCA28"
451 | exports.amber500 = "#FFC107"
452 | exports.amber600 = "#FFB300"
453 | exports.amber700 = "#FFA000"
454 | exports.amber800 = "#FF8F00"
455 | exports.amber900 = "#FF6F00"
456 | exports.amberA100 = "#FFE57F"
457 | exports.amberA200 = "#FFD740"
458 | exports.amberA400 = "#FFC400"
459 | exports.amberA700 = "#FFAB00"
460 | #orange------------------
461 | exports.orange = "#FF9800"
462 | exports.orange50 = "#FFF3E0"
463 | exports.orange100 = "#FFE0B2"
464 | exports.orange200 = "#FFCC80"
465 | exports.orange300 = "#FFB74D"
466 | exports.orange400 = "#FFA726"
467 | exports.orange500 = "#FF9800"
468 | exports.orange600 = "#FB8C00"
469 | exports.orange700 = "#F57C00"
470 | exports.orange800 = "#EF6C00"
471 | exports.orange900 = "#E65100"
472 | exports.orangeA100 = "#FFD180"
473 | exports.orangeA200 = "#FFAB40"
474 | exports.orangeA400 = "#FF9100"
475 | exports.orangeA700 = "#FF6D00"
476 | #deep orange-------------
477 | exports.deepOrange = "#FF5722"
478 | exports.deepOrange50 = "#FBE9E7"
479 | exports.deepOrange100 = "#FFCCBC"
480 | exports.deepOrange200 = "#FFAB91"
481 | exports.deepOrange300 = "#FF8A65"
482 | exports.deepOrange400 = "#FF7043"
483 | exports.deepOrange500 = "#FF5722"
484 | exports.deepOrange600 = "#F4511E"
485 | exports.deepOrange700 = "#E64A19"
486 | exports.deepOrange800 = "#D84315"
487 | exports.deepOrange900 = "#BF360C"
488 | exports.deepOrangeA100 = "#FF9E80"
489 | exports.deepOrangeA200 = "#FF6E40"
490 | exports.deepOrangeA400 = "#FF3D00"
491 | exports.deepOrangeA700 = "#DD2C00"
492 | #brown-------------
493 | exports.brown = "#795548"
494 | exports.brown50 = "#EFEBE9"
495 | exports.brown100 = "#D7CCC8"
496 | exports.brown200 = "#BCAAA4"
497 | exports.brown300 = "#A1887F"
498 | exports.brown400 = "#8D6E63"
499 | exports.brown500 = "#795548"
500 | exports.brown600 = "#6D4C41"
501 | exports.brown700 = "#5D4037"
502 | exports.brown800 = "#4E342E"
503 | exports.brown900 = "#4E342E"
504 | exports.brownA100 = ""
505 | exports.brownA200 = ""
506 | exports.brownA400 = ""
507 | exports.brownA700 = ""
508 | #grey--------------
509 | exports.grey = "#9E9E9E"
510 | exports.grey50 = "#FAFAFA"
511 | exports.grey100 = "#F5F5F5"
512 | exports.grey200 = "#EEEEEE"
513 | exports.grey300 = "#E0E0E0"
514 | exports.grey400 = "#BDBDBD"
515 | exports.grey500 = "#9E9E9E"
516 | exports.grey600 = "#757575"
517 | exports.grey700 = "#616161"
518 | exports.grey800 = "#424242"
519 | exports.grey900 = "#212121"
520 | exports.greyA100 = ""
521 | exports.greyA200 = ""
522 | exports.greyA400 = ""
523 | exports.greyA700 = ""
524 | #blue grey------------
525 | exports.blueGrey = "#607D8B"
526 | exports.blueGrey50 = "#ECEFF1"
527 | exports.blueGrey100 = "#CFD8DC"
528 | exports.blueGrey200 = "#B0BEC5"
529 | exports.blueGrey300 = "#90A4AE"
530 | exports.blueGrey400 = "#78909C"
531 | exports.blueGrey500 = "#607D8B"
532 | exports.blueGrey600 = "#546E7A"
533 | exports.blueGrey700 = "#455A64"
534 | exports.blueGrey800 = "#37474F"
535 | exports.blueGrey900 = "#263238"
536 |
537 | #black and white---------
538 | exports.black = "#000"
539 | exports.white = "#fff"
540 |
541 | #labels - light --------
542 | exports.lightPrimary = "rgba(0,0,0,0.87)"
543 | exports.lightSecondary = "rgba(0,0,0,0.54)"
544 | exports.lightDisabled = "rgba(0,0,0,0.38)"
545 |
546 | #labels - Dark --------
547 | exports.darkPrimary = "rgba(255,255,255,1)"
548 | exports.darkSecondary = "rgba(255,255,255, 0.7)"
549 | exports.darkDisabled = "rgba(255,255,255,0.5)"
550 |
551 |
552 |
553 |
554 |
555 |
556 | ################################################# 2. FlatButton ####################################################
557 | class exports.FlatButton extends Layer
558 |
559 | constructor: (@options={}) ->
560 |
561 | #------ Default properties --------------------------------------------------------------------------------------------
562 |
563 | Utils.insertCSS('@import url(https://fonts.googleapis.com/css?family=Roboto);')
564 |
565 | @options.labelText ?= "Flat Button"
566 | @options.themeColor ?= "#009688"
567 | @options.disabled ?= false
568 | @options.theme ?= "light"
569 | @options.directionRipple ?= false
570 | @options.fontFamily ?= "'Roboto', sans serif"
571 | @options.disableRipple ?= false
572 | @options.letterSpacing ?= 0
573 | @options.fontWeight ?= 600
574 | @options.fontSize ?= 14
575 |
576 | if @options.disabled is true
577 | if @options.theme is "dark"
578 | @disabled_labelColor = "rgba(255,255,255,0.3)"
579 | else
580 | @disabled_labelColor = "rgba(0,0,0,0.26)"
581 |
582 |
583 | _.defaults @options,
584 | backgroundColor : null
585 | height: 48
586 | borderRadius : 2
587 | width: @options.labelText.length * ((@options.fontSize + 3) / 2) + 16 + 16
588 | name: "Flat button"
589 |
590 |
591 | if @options.width < 88
592 | @options.width = 88
593 |
594 | if @options.dense is true
595 | @options.width = @options.labelText.length * ((@options.fontSize + 2) / 2) + 16 + 16
596 | @buttonHeight = 32
597 | else
598 | @buttonHeight = 36
599 |
600 | #------ hover ---------------------------------------------------------------------------------------------------------
601 |
602 | @bttnBG = new Layer
603 | width: @options.width
604 | height: @buttonHeight
605 | backgroundColor: @options.themeColor
606 | clip: true
607 | borderRadius: 2
608 | opacity: 0.12
609 | visible: false
610 | name: "overlay"
611 |
612 | #------- ripple -------------------------------------------------------------------------------------------------------
613 |
614 | @rippleBG = new Layer
615 | width: @options.width
616 | height: @buttonHeight
617 | backgroundColor: null
618 | name: "ripple parent"
619 |
620 |
621 | @ripple = new Layer
622 | borderRadius: "100%"
623 | size: @options.width
624 | backgroundColor: @options.themeColor
625 | scale: 0.3
626 | opacity: 0
627 | name: "ripple"
628 |
629 | #------- label -----------------------------------------------------------------------------------------------------
630 |
631 | @label = new TextLayer
632 | text : @options.labelText
633 | fontSize: @options.fontSize
634 | textTransform: "Uppercase"
635 | color: @options.themeColor
636 | fontWeight: @options.fontWeight
637 | fontFamily: @options.fontFamily
638 | letterSpacing: @options.letterSpacing
639 | name: "label"
640 |
641 | #------- super -----------------------------------------------------------------------------------------------------
642 |
643 | super @options
644 |
645 | @bttnBG.parent = @label.parent = @rippleBG.parent = @
646 | @bttnBG.y = Align.center
647 | @rippleBG.y = Align.center
648 |
649 | @rippleBG.clip = true
650 |
651 | @ripple.parent = @rippleBG
652 | @ripple.x = Align.center
653 | @ripple.y = Align.center
654 |
655 | @label.x = Align.center
656 | @label.y = Align.center(1)
657 |
658 | if @disableRipple is false
659 | @ripple.destroy()
660 |
661 | #-------- Events ----------------------------------------------------------------------------------------------------
662 |
663 | @.onClick @clicked
664 | @.onMouseOver @Hover
665 | @.onMouseOut @HoverOff
666 | @.onMouseDown @mouseDown
667 | @.onMouseUp @mouseUp
668 |
669 | #-------- getters & setters -------------------------------------------------------------------------------------------
670 |
671 | @define 'disabled',
672 | get: ->
673 | @options.disabled
674 | set: (value) ->
675 | @options.disabled = value
676 |
677 | if @options.disabled is true
678 | @label.color = @disabled_labelColor
679 |
680 | if @options.disabled is false
681 | @label.color = @options.themeColor
682 |
683 |
684 |
685 | #--------- Event functions -------------------------------------------------------------------------------------------
686 |
687 | Hover: =>
688 | if @options.disabled is false
689 | @bttnBG.visible = true
690 |
691 | HoverOff: =>
692 | @bttnBG.visible = false
693 |
694 | mouseDown: ->
695 | @bttnBG.brightness = 80
696 | mouseUp: ->
697 | @bttnBG.brightness = 100
698 |
699 | clicked: (ev) ->
700 | if @options.disabled is false
701 | if @options.disableRipple is false
702 |
703 | if @options.directionRipple is true
704 | @ripple.midX = ev.offsetX
705 | @ripple.midY = ev.offsetY
706 | @ripple.size = (@options.labelText.length * 8.5 + 16 + 16) * 1.5
707 |
708 | @ripple.visible = true
709 | @ripple.scale = 0.4
710 | @ripple.opacity = 0.3
711 |
712 | rippleA = new Animation
713 | layer: @ripple
714 | properties:
715 | scale: 0.8
716 | time: 0.15
717 | curve: Bezier.linear
718 |
719 | rippleB = new Animation
720 | layer: @ripple
721 | properties:
722 | scale: 1
723 | opacity: 0
724 | time: 0.15
725 | curve: Bezier.linear
726 |
727 | rippleA.start()
728 |
729 | rippleA.onAnimationEnd ->
730 | rippleB.start()
731 |
732 |
733 |
734 |
735 |
736 | ################################################# 3. RaisedButton ##################################################
737 | class exports.RaisedButton extends Layer
738 |
739 | constructor: (@options={}) ->
740 |
741 | #------ Default properties --------------------------------------------------------------------------------------------
742 |
743 | Utils.insertCSS('@import url(https://fonts.googleapis.com/css?family=Roboto);')
744 |
745 | @options.labelText ?= "Raised button"
746 | @options.themeColor ?= "#009688"
747 | @options.disabled ?= false
748 | @options.theme ?= "light"
749 | @options.directionRipple ?= false
750 | @options.fontFamily ?= "'Roboto', sans serif"
751 | @options.height = 48
752 | @options.disableRipple ?= false
753 | @options.letterSpacing ?= 0
754 | @options.fontWeight ?= 600
755 | @options.fontSize ?= 14
756 |
757 | if @options.disabled is true
758 | if @options.theme is "dark"
759 | @disabled_BG = "rgba(255,255,255,0.12)"
760 | @disabled_labelColor = "rgba(255,255,255,0.3)"
761 | else
762 | @disabled_BG = "rgba(0,0,0,0.12)"
763 | @disabled_labelColor = "rgba(0,0,0,0.26)"
764 |
765 | _.defaults @options,
766 | backgroundColor : ""
767 | color: ""
768 | borderRadius : 2
769 | name: "Raised button"
770 | width: @options.labelText.length * ((@options.fontSize + 3) / 2) + 16 + 16
771 |
772 | if @options.width < 88
773 | @options.width = 88
774 |
775 | if @options.dense is true
776 | @buttonHeight = 32
777 | else
778 | @buttonHeight = 36
779 |
780 | #-------Shadows -------------------------------------------------------------------------------------------------------
781 |
782 | @shadow = new Shadow
783 | width: @options.width
784 | height: @buttonHeight
785 | backgroundColor : @options.themeColor
786 | borderRadius: @options.borderRadius
787 | name: "shadows"
788 |
789 |
790 |
791 | #-------hover --------------------------------------------------------------------------------------------------------
792 |
793 | @bttnBG = new Layer
794 | width: @options.width
795 | height: @buttonHeight
796 | backgroundColor: "#fff"
797 | clip: true
798 | borderRadius: 2
799 | opacity: 0
800 | name: "overlay"
801 |
802 | #-------ripple ---------------------------------------------------------------------------------------------------------
803 |
804 | @rippleBG = new Layer
805 | width: @options.width
806 | height: @buttonHeight
807 | clip: true
808 | borderRadius: 2
809 | name: "ripple parent"
810 | clip: true
811 | backgroundColor: ""
812 |
813 |
814 | @ripple = new Layer
815 | borderRadius: "100%"
816 | size: @options.width
817 | backgroundColor: "#fff"
818 | scale:0.3
819 | opacity: 0
820 | name: "ripple"
821 |
822 | @rippleColor = @ripple.backgroundColor
823 |
824 | #-------label ---------------------------------------------------------------------------------------------------------
825 |
826 | @label = new TextLayer
827 | text : @options.labelText
828 | fontSize: @options.fontSize
829 | textTransform: "Uppercase"
830 | color: "#fff"
831 | fontWeight: @options.fontWeight
832 | fontFamily: @options.fontFamily
833 | letterSpacing: @options.letterSpacing
834 | name: "label"
835 |
836 | #-------super --------------------------------------------------------------------------------------------------------
837 |
838 | super @options
839 |
840 | @label.parent = @rippleBG.parent = @shadow.parent = @bttnBG.parent = @
841 |
842 | @shadow.y = @bttnBG.y = @rippleBG.y = Align.center
843 |
844 | @ripple.parent = @rippleBG
845 | @ripple.x = Align.center
846 | @ripple.y = Align.center
847 |
848 | @label.x = Align.center
849 | @label.y = Align.center(1)
850 |
851 | if @disableRipple is false
852 | @ripple.destroy()
853 |
854 | #---------Events -----------------------------------------------------------------------------------------------------
855 |
856 | @.onClick @clicked
857 | @.onMouseOver @Hover
858 | @.onMouseOut @HoverOff
859 | @.onMouseDown @mouseDown
860 | @.onMouseUp @mouseUp
861 |
862 | #---------getters & setters -----------------------------------------------------------------------------------------
863 |
864 | @define 'disabled',
865 | get: ->
866 | @options.disabled
867 | set: (value) ->
868 | @options.disabled = value
869 |
870 | if @options.disabled is true
871 | @label.color = @disabled_labelColor
872 | @shadow.backgroundColor = @disabled_BG
873 | else
874 | @shadow.backgroundColor = @options.themeColor
875 | @label.color = "#fff"
876 |
877 | #---------Event functions ------------------------------------------------------------------------------------------
878 |
879 | Hover: =>
880 | if @options.disabled is false
881 | @bttnBG.opacity = 0.12
882 | for item in @shadow.array
883 | item.states.switch "_8dp"
884 | HoverOff: =>
885 | @bttnBG.opacity = 0
886 | for item in @shadow.array
887 | item.states.switch "_2dp"
888 |
889 | mouseDown: ->
890 | if @options.disabled is false
891 | @brightness = 80
892 | @bttnBG.opacity = 0
893 | mouseUp: ->
894 | @brightness = 100
895 |
896 | clicked: (ev) ->
897 | if @options.disabled is false
898 | if @options.disableRipple is false
899 |
900 | if @options.directionRipple is true
901 | @ripple.midX = ev.offsetX
902 | @ripple.midY = ev.offsetY
903 | @ripple.size = (@options.labelText.length * 8.5 + 16 + 16) * 1.5
904 |
905 | @ripple.visible = true
906 | @ripple.scale = 0.4
907 | @ripple.opacity = 0.3
908 |
909 | rippleA = new Animation
910 | layer: @ripple
911 | properties:
912 | scale: 0.8
913 | time: 0.15
914 | curve: Bezier.linear
915 |
916 | rippleB = new Animation
917 | layer: @ripple
918 | properties:
919 | scale: 1
920 | opacity: 0
921 | time: 0.15
922 | curve: Bezier.linear
923 |
924 | rippleA.start()
925 |
926 | rippleA.onAnimationEnd ->
927 | rippleB.start()
928 |
929 |
930 |
931 |
932 |
933 | ################################################# 4. FAB ###########################################################
934 | class exports.FAB extends Layer
935 | constructor: (@options={}) ->
936 |
937 | #------ Default properties --------------------------------------------------------------------------------------------
938 |
939 | if Utils.isDesktop()
940 | pd = 24
941 | else pd = 16
942 |
943 | @options.mini ?= false
944 |
945 | if @options.mini is true or Screen.width < 460
946 | @options.width ?= 40
947 | @options.height ?= 40
948 | else
949 | @options.width ?= 56
950 | @options.height ?= 56
951 |
952 | @options.x ?= Screen.width - (@options.width + pd)
953 | @options.y ?= Screen.height - (@options.width + pd)
954 |
955 | @options.borderRadius = "100%"
956 | @options.themeColor ?= "#009688"
957 | @options.backgroundColor ?= @options.themeColor
958 | @options.icon ?= "add"
959 |
960 | #------ overlay -----------------------------------------------------------------------------------------------------
961 |
962 | @overlay = new Layer
963 | width: @options.width
964 | height: @options.height
965 | borderRadius: @options.borderRadius
966 | backgroundColor: "rgba(0,0,0,0.12)"
967 | visible: false
968 | name: "overlay"
969 |
970 | #------ shadow -----------------------------------------------------------------------------------------------------
971 |
972 | @shadow = new Shadow
973 | width: @options.width
974 | height: @options.height
975 | borderRadius: @options.borderRadius
976 | name: "shadow"
977 |
978 | @shadow.umbra.states.switchInstant "_6dp"
979 | @shadow.penumbra.states.switchInstant "_6dp"
980 | @shadow.ambient.states.switchInstant "_6dp"
981 |
982 | #------ icon -----------------------------------------------------------------------------------------------------
983 |
984 | @icon = new SystemIcon
985 | width: 24
986 | height: 24
987 | icon: @options.icon
988 | color: "#fff"
989 | name: "icon"
990 |
991 | #------ super -----------------------------------------------------------------------------------------------------
992 |
993 | super @options
994 |
995 | @icon.parent = @overlay.parent = @shadow.parent = @
996 | @icon.center()
997 |
998 | #------ events -----------------------------------------------------------------------------------------------------
999 |
1000 | if Utils.isDesktop()
1001 | @.onMouseOver @Hover
1002 | @.onMouseOut @HoverOff
1003 | @onMouseDown @mouseDown
1004 | @onMouseUp @mouseUp
1005 | else
1006 | @onTapStart @mouseDown
1007 | @onTapEnd @mouseUp
1008 |
1009 | #------ event functions ---------------------------------------------------------------------------------------------
1010 |
1011 | Hover: ->
1012 | @shadow.umbra.states.switch "_12dp"
1013 | @shadow.penumbra.states.switch "_12dp"
1014 | @shadow.ambient.states.switch "_12dp"
1015 |
1016 | HoverOff: ->
1017 | @shadow.umbra.states.switch "_6dp"
1018 | @shadow.penumbra.states.switch "_6dp"
1019 | @shadow.ambient.states.switch "_6dp"
1020 |
1021 | mouseDown: ->
1022 | @overlay.visible = true
1023 | @shadow.umbra.states.switchInstant "_12dp"
1024 | @shadow.penumbra.states.switchInstant "_12dp"
1025 | @shadow.ambient.states.switchInstant "_12dp"
1026 |
1027 | mouseUp: ->
1028 | @overlay.visible = false
1029 | @shadow.umbra.states.switchInstant "_6dp"
1030 | @shadow.penumbra.states.switchInstant "_6dp"
1031 | @shadow.ambient.states.switchInstant "_6dp"
1032 |
1033 |
1034 |
1035 |
1036 |
1037 | ################################################# 5. Checkboxes #####################################################
1038 | class exports.Checkboxes extends Layer
1039 |
1040 | constructor: (@options={}) ->
1041 |
1042 | #------ default properties --------------------------------
1043 |
1044 | @options.theme ?= "light"
1045 | theme = @options.theme
1046 | @options.name ?= "checkboxes"
1047 |
1048 | @options.disableRipple ?= false
1049 |
1050 | if @options.theme is "dark"
1051 | @options.screenColor ?= "#212121"
1052 | else
1053 | @options.screenColor ?= "#fff"
1054 |
1055 | #label choices
1056 | @options.choices ?= ["apples", "bananas", "grapes"]
1057 |
1058 | @options.checkY ?= -5
1059 |
1060 | #------ colors
1061 | @themeColor ?= "#009688"
1062 | themeColor = @themeColor
1063 |
1064 | if @options.theme is "dark"
1065 | @labelColor = label_dark
1066 | @boxColor = line_dark
1067 | else
1068 | @labelColor = label_light
1069 | @boxColor = line_light
1070 | boxColor = @boxColor
1071 |
1072 | #text styling
1073 | Utils.insertCSS('@import url(https://fonts.googleapis.com/css?family=Roboto);')
1074 |
1075 | @options.labelText ?= "Select fruit"
1076 |
1077 | #Default properties
1078 | _.defaults @options,
1079 | backgroundColor : ""
1080 | height: @options.choices.length * 36 + 32
1081 | width : 150
1082 |
1083 | #------ Question label --------------------------------------------------------------------------------------------
1084 |
1085 | @label = new Label
1086 | color: @labelColor
1087 | text: @options.labelText
1088 | name: "label"
1089 |
1090 | #------ Super ------------------------------------------------------------------------------------------------------
1091 | super @options
1092 |
1093 | @label.parent = @
1094 |
1095 | checkY = @options.checkY
1096 |
1097 | #------ time --------------------------------------------------------------------------------------------------------
1098 | t1 = 0.2
1099 | t2 = 0.2
1100 |
1101 | #------ loop ------------------------------------------------------------------------------------------------
1102 | checks = []
1103 |
1104 | for i in [0...@options.choices.length]
1105 |
1106 | #------ checkbox container
1107 | cont = new Layer
1108 | parent:@
1109 | height: 40
1110 | y: i * 40 + 24
1111 | backgroundColor: ""
1112 | x: 16
1113 | name: "container"
1114 |
1115 | #------ box settings
1116 | box = new Layer
1117 | backgroundColor : ""
1118 | size : 20
1119 | borderRadius : 2
1120 | borderWidth : 2
1121 | borderColor : @boxColor
1122 | parent: cont
1123 | clip: true
1124 | name: @options.choices[i]
1125 | y: Align.center
1126 | name: @options.choices[i]
1127 |
1128 | box.animationOptions =
1129 | time: t1
1130 |
1131 | box.states =
1132 | selected:
1133 | borderColor: @options.themeColor
1134 | backgroundColor: @options.themeColor
1135 | deselected:
1136 | borderColor: @boxColor
1137 | backgroundColor: @boxColor
1138 |
1139 | box.states.switchInstant "deselected"
1140 | box.backgroundColor = @options.screenColor
1141 |
1142 | #------ box Circle settings
1143 | #------ This create the circle animation within the box
1144 | boxCircle = new Layer
1145 | parent: box
1146 | borderRadius: "100%"
1147 | size: 30
1148 | scale: 0
1149 | backgroundColor: @screenColor
1150 | x: Align.center(2)
1151 | y: Align.center(2)
1152 | name: "overlay"
1153 |
1154 | boxCircle.animationOptions =
1155 | time: t1
1156 |
1157 | boxCircle.states =
1158 | selected:
1159 | scale: 0
1160 | deselected:
1161 | scale: 1
1162 | backgroundColor: @options.screenColor
1163 |
1164 | #------ check mask settings
1165 | #------ This create drawing in effect for the check
1166 | checkMask = new Layer
1167 | width: 0
1168 | height: 20
1169 | backgroundColor: ""
1170 | parent: box
1171 | y: checkY
1172 | x: 3.5
1173 | parent: box
1174 | clip: true
1175 | name: "check mask"
1176 |
1177 | checkMask.states.selected =
1178 | properties:
1179 | width:20
1180 | time: t2
1181 |
1182 | checkMask.states.deselected =
1183 | properties:
1184 | width: 0
1185 | time: 0.01
1186 |
1187 | checkMask.states.switch "deselected"
1188 |
1189 | #------ check settings
1190 | check = new Layer
1191 | html: ' '
1192 | width: 20
1193 | height: 20
1194 | backgroundColor: ""
1195 | parent: checkMask
1196 | name: @options.choices[i]
1197 | y: 0
1198 | name: "check"
1199 |
1200 | check.style =
1201 | fontSize: "18px"
1202 |
1203 | #------ Ripple settings
1204 | if @options.disableRipple is false
1205 |
1206 | ripple = new Layer
1207 | size: 50
1208 | borderRadius: "100px"
1209 | parent: cont
1210 | y: Align.center
1211 | x: -15
1212 | opacity: 0.3
1213 | visible: false
1214 | name: "ripple"
1215 |
1216 | ripple.states.selected =
1217 | backgroundColor: @options.themeColor
1218 |
1219 | if @options.theme is "light"
1220 | ripple.states.deselected =
1221 | backgroundColor: "#000"
1222 |
1223 | if @options.theme is "dark"
1224 | ripple.states.deselected =
1225 | backgroundColor: "#fff"
1226 |
1227 | #------ choise lables settings
1228 | choice_label = new Label
1229 | text: @options.choices[i]
1230 | parent: cont
1231 | x: 30
1232 | color: @labelColor
1233 | y: Align.center(-0.5)
1234 | name: "choice ripple"
1235 |
1236 | #------ populating checks array
1237 | checks.push(box)
1238 |
1239 | #------ creating new array to see what checks are selected
1240 | ao = @options
1241 | dp = @options.disableRipple
1242 | ao.activeSelection = []
1243 |
1244 | #------ event on Click ---------------------------------------------------------------------------------------------
1245 | cont.onClick ->
1246 |
1247 | #------ event setup
1248 | ao.activeSelection = [] #empty array
1249 |
1250 | if dp is false
1251 | pRipple = this.children[1]
1252 | pCheckMask = this.children[0].children[1]
1253 | pBox = this.children[0]
1254 | pBoxCircle = this.children[0].children[0]
1255 |
1256 | #------ box and check animation
1257 | pBox.stateCycle("selected", "deselected")
1258 | pBoxCircle.stateCycle("selected", "deselected")
1259 |
1260 | if pBox.states.current.name is "selected"
1261 | if dp is false
1262 | pRipple.states.switchInstant "selected"
1263 | Utils.delay t1, ->
1264 | pCheckMask.states.switch "selected"
1265 | else
1266 | if dp is false
1267 | pRipple.states.switchInstant "deselected"
1268 | pCheckMask.states.switch "deselected"
1269 |
1270 | # populates array to see selected items
1271 | for box in checks
1272 | if box.states.current.name is "selected"
1273 | ao.activeSelection.push(box.name)
1274 |
1275 | #----- pRipple animation
1276 | if dp is false
1277 | pRipple.visible = true
1278 | pRipple.scale = 0.4
1279 | pRipple.opacity = 0.4
1280 |
1281 | if pRipple.states.current.name is "selected"
1282 | pRipple.opacity = 0.8
1283 |
1284 | pulsaA = new Animation
1285 | layer: pRipple
1286 | properties:
1287 | scale: 0.8
1288 | time: 0.15
1289 | curve: Bezier.linear
1290 |
1291 | pRippleB = new Animation
1292 | layer: pRipple
1293 | properties:
1294 | scale: 1
1295 | opacity: 0
1296 | time: 0.15
1297 | curve: Bezier.linear
1298 |
1299 | pulsaA.start()
1300 |
1301 | pulsaA.onAnimationEnd ->
1302 | pRippleB.start()
1303 |
1304 | #------ event hover
1305 | cont.onMouseOver ->
1306 | this.children[0].borderColor = themeColor
1307 |
1308 | cont.onMouseOut ->
1309 | if this.children[0].states.current.name is "deselected"
1310 | this.children[0].borderColor = boxColor
1311 |
1312 | #------ getters and setters ---------------------------------------------------------------------------------------
1313 | @define 'themeColor',
1314 | get: ->
1315 | @options.themeColor
1316 | set: (value) ->
1317 | @options.themeColor = value
1318 |
1319 | @define 'choices',
1320 | get: ->
1321 | @options.choices
1322 | set: (value) ->
1323 | @options.choices = value
1324 |
1325 | @define 'activeSelection',
1326 | get: ->
1327 | @options.activeSelection
1328 | set: (value) ->
1329 | @options.activeSelection = value
1330 |
1331 |
1332 |
1333 |
1334 |
1335 | ################################################# 6. RadioButtons ####################################################
1336 | class exports.RadioButtons extends Layer
1337 |
1338 | constructor: (@options={}) ->
1339 |
1340 | #------ default properties -----------------------------------------------------------------------------------------
1341 | @options.theme ?= "light"
1342 | theme = @options.theme
1343 |
1344 | @options.disableRipple ?= false
1345 |
1346 | #label choices
1347 | @options.choices ?= ["apples", "bananas", "grapes"]
1348 |
1349 | #------- colors
1350 | @options.themeColor ?= "#009688"
1351 | themeColor = @options.themeColor
1352 |
1353 | if @options.theme is "dark"
1354 | @labelColor = label_dark
1355 | @boxColor = line_dark
1356 | else
1357 | @labelColor = label_light
1358 | @boxColor = line_light
1359 | boxColor = @boxColor
1360 |
1361 | @options.labelText ?= "Select fruit"
1362 |
1363 | _.defaults @options,
1364 | backgroundColor : ""
1365 | height: @options.choices.length * 36 + 32
1366 | width : 150
1367 | name: "RadioButtons"
1368 |
1369 | #------ Question label ---------------------------------------------------------------------------------------------
1370 |
1371 | @label = new Label
1372 | text: @options.labelText
1373 | color: @labelColor
1374 | name: "label"
1375 |
1376 | #------ Super ------------------------------------------------------------------------------------------------------
1377 |
1378 | super @options
1379 |
1380 | @label.parent = @
1381 |
1382 | l = @options.choices
1383 |
1384 | #------ loop and array ---------------------------------------------------------------------------------------------
1385 |
1386 | checks = []
1387 | circles = []
1388 |
1389 | for i in [0...@options.choices.length]
1390 |
1391 | cont = new Layer
1392 | height: 40
1393 | y: 40 * i + 24
1394 | backgroundColor: ""
1395 | parent: @
1396 | name: @options.choices[i]
1397 | x: 16
1398 |
1399 | #------ circle
1400 |
1401 | circle = new Layer
1402 | backgroundColor : ""
1403 | size : 20
1404 | borderRadius : "100%"
1405 | borderWidth : 2
1406 | borderColor: @boxColor
1407 | parent: cont
1408 | y: Align.center
1409 | name: "circle"
1410 |
1411 | circle.animationOptions =
1412 | time: 0.001
1413 |
1414 | circle.states =
1415 | selected:
1416 | borderColor: themeColor
1417 | deselected:
1418 | borderColor: @boxColor
1419 |
1420 | circles.push(circle)
1421 | circle.states.switch "deselected"
1422 |
1423 | if i is @options.activeSelection
1424 | circle.states.switchInstant "selected"
1425 |
1426 | #------ check
1427 |
1428 | check = new Layer
1429 | width: 10
1430 | height: 10
1431 | backgroundColor: @options.themeColor
1432 | borderRadius: circle.borderRadius
1433 | parent: circle
1434 | x: 5
1435 | y: 5
1436 | name: i
1437 |
1438 | check.animationOptions =
1439 | time: 0.17
1440 |
1441 | check.states =
1442 | selected:
1443 | scale: 1
1444 | deselected:
1445 | scale: 0
1446 |
1447 | check.states.switchInstant "deselected"
1448 |
1449 | checks.push(check)
1450 |
1451 | if i is @options.activeSelection
1452 | check.states.switchInstant "selected"
1453 |
1454 | #------ ripple settings
1455 |
1456 | if @options.disableRipple is false
1457 |
1458 | ripple = new Layer
1459 | size: 50
1460 | borderRadius: "100px"
1461 | parent: circle
1462 | y: Align.center(2)
1463 | x: Align.center(2)
1464 | opacity: 0.12
1465 | visible: false
1466 | backgroundColor: @options.themeColor
1467 | name: "ripple"
1468 |
1469 | #------ choice
1470 |
1471 | choice_label = new Label
1472 | text: @options.choices[i]
1473 | parent: cont
1474 | x: 30
1475 | color: @labelColor
1476 | y: -0.5
1477 | y: Align.center
1478 | name: "choice label"
1479 |
1480 | #------ helper
1481 |
1482 | helper = new Layer
1483 | backgroundColor: ""
1484 | height: 5
1485 | parent: cont
1486 | width: i
1487 | name: "helper"
1488 |
1489 | #------ event
1490 |
1491 | @activeSelection = null
1492 | bb = @activeSelection
1493 | dp = @options.disableRipple
1494 | oc = @themeColor
1495 |
1496 | cont.onClick ->
1497 |
1498 | pRipple = this.children[0].children[1]
1499 | pCheck = this.children[0].children[0]
1500 | pCircle = this.children[0]
1501 |
1502 | for check in checks
1503 | if check.name is pCheck.name
1504 | pCheck.states.switch "selected"
1505 | else
1506 | check.states.switch "deselected"
1507 | for circle in circles
1508 | circle.states.switch "deselected"
1509 |
1510 | pCircle.states.switchInstant "selected"
1511 |
1512 | bb = this.name
1513 |
1514 | #------ ripple animation
1515 |
1516 | if dp is false
1517 | pRipple.visible = true
1518 | pRipple.scale = 0.4
1519 | pRipple.opacity = 0.2
1520 |
1521 | if pRipple.states.current.name is "selected"
1522 | pRipple.opacity = 0.3
1523 |
1524 | RippleA = new Animation
1525 | layer: pRipple
1526 | properties:
1527 | scale: 0.8
1528 | time: 0.15
1529 | curve: Bezier.linear
1530 |
1531 | RippleB = new Animation
1532 | layer: pRipple
1533 | properties:
1534 | scale: 1
1535 | opacity: 0
1536 | time: 0.15
1537 | curve: Bezier.linear
1538 |
1539 | RippleA.start()
1540 |
1541 | RippleA.onAnimationEnd ->
1542 | RippleB.start()
1543 |
1544 | #------ event -----------------------------------------------------------------------------------------------------
1545 |
1546 | cont.onMouseOver ->
1547 | this.children[0].borderColor = themeColor
1548 |
1549 | cont.onMouseOut ->
1550 | if this.children[0].states.current.name is "deselected"
1551 | this.children[0].borderColor = boxColor
1552 |
1553 | @onClick ->
1554 | @options.activeSelection = bb
1555 |
1556 | #------ getter and setter -----------------------------------------------------------------------------------------
1557 |
1558 | @define 'activeSelection',
1559 | get: -> @options.activeSelection
1560 | set: (value) -> @options.activeSelection = value
1561 |
1562 | @define 'theme',
1563 | get: -> @options.theme
1564 | set: (value) -> @options.theme = value
1565 |
1566 |
1567 |
1568 |
1569 |
1570 | ################################################# 7. Switch #########################################################
1571 | class exports.Switch extends Layer
1572 |
1573 | constructor: (@options={}) ->
1574 |
1575 | #------ Custome properties -----------------------------------------------------------------------------------------
1576 |
1577 | @options.disableRipple ?= false
1578 | @options.activeOnStart ?= false
1579 | @options.active ?= false
1580 |
1581 | @options.theme ?= "light"
1582 | theme = @options.theme
1583 |
1584 | #------ colors
1585 | @options.themeColor ?= "#009688"
1586 | themeColor = @options.themeColor
1587 | @thumbColor = @options.themeColor
1588 | @trackColor = @options.themeColor
1589 | @thumb_light_off = "#FAFAFA"
1590 | @thumb_dark_off = "#bdbdbd"
1591 | @track_light_off = "rgba(0,0,0,0.38)"
1592 | @track_dark_off = "rgba(255,255,255,0.3)"
1593 | @ripple_dark_off = "rgba(255,255,255, 1)"
1594 | @ripple_light_off = "rgba(0,0,0, 1)"
1595 |
1596 | if @options.theme is "dark"
1597 | @labelColor = label_dark
1598 | @thumbOff = @thumb_dark_off
1599 | @trackOff = @track_dark_off
1600 | @rippleOff = @ripple_dark_off
1601 | else
1602 | @labelColor = label_light
1603 | @thumbOff = @thumb_light_off
1604 | @trackOff = @track_light_off
1605 | @rippleOff = @ripple_light_off
1606 |
1607 | Utils.insertCSS('@import url(https://fonts.googleapis.com/css?family=Roboto);')
1608 |
1609 | _.defaults @options,
1610 | backgroundColor : ""
1611 | height: 48
1612 | width : 150
1613 |
1614 | #------ track ---------------------------------------------------------------------------------------------------
1615 |
1616 | @track = new Layer
1617 | width: 40
1618 | height: 15
1619 | borderRadius: 15
1620 | name: "track"
1621 | @track.animationOptions =
1622 | time: 0.2
1623 |
1624 | @track.states =
1625 | on:
1626 | backgroundColor: @options.themeColor
1627 | opacity: 0.5
1628 | off:
1629 | backgroundColor: @trackOff
1630 | opacity: 0.38
1631 |
1632 | delete @track.states.default
1633 | @track.states.switchInstant "off"
1634 |
1635 | #------ ripple -------------------------------------------------------------------------------------------------
1636 |
1637 | @ripple = new Layer
1638 | size: 50
1639 | scale: 1
1640 | borderRadius: 50
1641 | opacity: 0.2
1642 | visible: false
1643 | name: "ripple"
1644 | backgroundColor: @options.themeColor
1645 |
1646 | #------ thumb -------------------------------------------------------------------------------------------------
1647 |
1648 | @thumb = new Layer
1649 | size: 19
1650 | borderRadius: 100
1651 | name: "thumb"
1652 | backgroundColor: @thumbOff
1653 | @thumb.animationOptions =
1654 | time: 0.3
1655 |
1656 | @thumb.states =
1657 | on:
1658 | x: 21
1659 | backgroundColor: @options.themeColor
1660 | off:
1661 | x: 0
1662 | backgroundColor: @thumbOff
1663 |
1664 | delete @thumb.states.default
1665 | @thumb.states.switchInstant "off"
1666 |
1667 | #------ label -------------------------------------------------------------------------------------------------
1668 |
1669 | @label = new Label
1670 | text: @options.labelText
1671 | color: @labelColor
1672 | name: "label"
1673 |
1674 | #------ Super -------------------------------------------------------------------------------------------------
1675 |
1676 | super @options
1677 |
1678 | @track.parent = @
1679 | @track.y = Align.center
1680 |
1681 | @thumb.parent = @
1682 | @thumb.y = Align.center
1683 |
1684 | @label.parent = @
1685 | @label.x = 55
1686 | @label.y = Align.center
1687 |
1688 | if @options.disableRipple is false
1689 | @ripple.parent = @thumb
1690 | @ripple.x = - 15
1691 | @ripple.y = - 15
1692 | ripple = @ripple
1693 |
1694 | #------ shadows -------------------------------------------------------------------------------------------------
1695 |
1696 | shadow = new Shadow
1697 | parent: @thumb
1698 | borderRadius: 100
1699 | width: @thumb.width
1700 | height: @thumb.width
1701 | name: "shadow"
1702 |
1703 | #------ activeOnStart ---------------------------------------------------------------------------------------------
1704 |
1705 | if @options.activeOnStart is true
1706 | @thumb.states.switchInstant "on"
1707 | @track.states.switchInstant "on"
1708 | @active = true
1709 |
1710 | #------ ripple animation ------------------------------------------------------------------------------------------
1711 |
1712 | rippleAni = ->
1713 |
1714 | ripple.visible = true
1715 | ripple.scale = 0.4
1716 |
1717 | pulsaA = new Animation
1718 | layer: ripple
1719 | properties:
1720 | scale: 0.8
1721 | time: 0.15
1722 | curve: Bezier.linear
1723 |
1724 | rippleB = new Animation
1725 | layer: ripple
1726 | properties:
1727 | scale: 1
1728 | opacity: 0
1729 | time: 0.15
1730 | curve: Bezier.linear
1731 | pulsaA.start()
1732 |
1733 | pulsaA.onAnimationEnd ->
1734 | rippleB.start()
1735 |
1736 | #------ event -------------------------------------------------------------------------------------------------
1737 |
1738 | state = null
1739 |
1740 | @onClick ->
1741 |
1742 | @track.stateCycle()
1743 | @thumb.stateCycle()
1744 |
1745 | if @options.disableRipple is false
1746 | if @thumb.states.current.name is "on"
1747 | @ripple.backgroundColor = @options.themeColor
1748 | @ripple.opacity = 0.4
1749 | posX = 20
1750 | rippleAni()
1751 | @options.active = true
1752 | else
1753 | posX = 0
1754 | @ripple.backgroundColor = @rippleOff
1755 | @ripple.opacity = 0.2
1756 | rippleAni()
1757 | @options.active = false
1758 |
1759 |
1760 | if @thumb.states.current.name is "on"
1761 | @options.active = true
1762 | else
1763 | @options.active = false
1764 |
1765 | #------ getters and setters --------------------------------------------------------------------------------------
1766 |
1767 | @define 'active',
1768 | get: ->
1769 | @options.active
1770 | set: (value) ->
1771 | @options.active = value
1772 |
1773 |
1774 |
1775 |
1776 |
1777 | ################################################# 8. TextField ######################################################
1778 | class TextField extends Layer
1779 |
1780 | INPUT_HIDE_PSUEDO_UI = "{ -webkit-appearance: none; display: none; }"
1781 | INPUT_SELECTOR_NUMBER = "input[type=number]::-webkit-inner-spin-button, input[type=number]::-webkit-outer-spin-button"
1782 | INPUT_SELECTOR_SEARCH = "input[type=search]::-webkit-search-cancel-button"
1783 |
1784 | Events.Input = "InputField.OnInput"
1785 | Events.Focus = "InputField.OnFocus"
1786 | Events.Blur = "InputField.OnBlur"
1787 | Events.Valid = "InputField.OnValid"
1788 | Events.Invalid = "InputField.OnInvalid"
1789 | Events.Match = "InputField.OnMatch"
1790 |
1791 | @define "value",
1792 | get: ->
1793 | @input.value
1794 |
1795 | set: (v) ->
1796 | return unless v
1797 | if @input
1798 | @changeInputValue v
1799 |
1800 | constructor: (@options={}) ->
1801 |
1802 | #------- default properties -----------------------------------------------------------------------------------------
1803 |
1804 | @isNumber = false
1805 | @isSearch = false
1806 |
1807 | @isEmpty = true
1808 | @isValid = null
1809 | @originalTextColor = null
1810 |
1811 | # Framer Layer Props
1812 | @options.name ?= "Basic text field"
1813 |
1814 | @options.borderRadius = 0
1815 | @options.placeHolderFocus ?= null
1816 | @options.placeHolderColor = ""
1817 | @options.placeHolder ?= ""
1818 |
1819 | @options.theme ?= "light"
1820 | theme = @options.theme
1821 |
1822 | #colors
1823 | @options.themeColor ?= "#009688"
1824 | themeColor = @themeColor
1825 |
1826 | if @options.theme is "dark"
1827 | @labelColor = Inputlabel_dark
1828 | @inputColor = input_dark
1829 | @lineColor = "rgba(255,255,255,0.7)"
1830 | @lineHoverColor = "rgba(255,255,255,1)"
1831 | @labelFocusOpacity = 1
1832 | @options.backgroundColor = "rgba(0,0,0,0.01)"
1833 | else
1834 | @labelColor = Inputlabel_light
1835 | @inputColor = input_light
1836 | @lineColor = "rgba(0,0,0,0.42)"
1837 | @lineHoverColor = "rgba(0,0,0,0.87)"
1838 | @labelFocusOpacity = 0.87
1839 | @options.backgroundColor = "rgba(255,255,255,0.01)"
1840 | boxColor = @boxColor
1841 |
1842 | @options.color = @inputColor
1843 |
1844 |
1845 | #text styling
1846 | Utils.insertCSS('@import url(https://fonts.googleapis.com/css?family=Roboto);')
1847 |
1848 | if Utils.isMobile()
1849 | @options.fontSize ?= 16 * 2
1850 | @options.lineHeight ?= 24 * 2
1851 | @options.lineHeight = "#{@options.lineHeight}px" if @options.lineHeight?
1852 | @options.height = 70
1853 | else
1854 | @options.fontSize ?= 16
1855 | @options.lineHeight ?= 24
1856 | @options.lineHeight = "#{@options.lineHeight}px" if @options.lineHeight?
1857 | @options.height = 70
1858 |
1859 | @options.labelSize ?=16
1860 |
1861 | @options.fontFamily ?= "'Roboto', sans serif"
1862 | @options.fontWeight ?= 400
1863 | @options.letterSpacing ?= 0
1864 |
1865 | #text html
1866 | @options.helperText ?= "Helper text"
1867 | @options.labelText ?= "Label"
1868 | @options.helperTextVisble ?= false
1869 |
1870 | #Default properties
1871 | _.defaults @options,
1872 | width : 200
1873 |
1874 | #------- Elements --------------------------------------------------------------------------------------------------
1875 |
1876 | @line = new Layer
1877 | width: @options.width
1878 | height: 1
1879 | clip: true
1880 | name: "line"
1881 | backgroundColor: @lineColor
1882 |
1883 | @lineRipple = new Layer
1884 | backgroundColor: @options.themeColor
1885 | width: 0
1886 | height: 2
1887 | name: "ripple"
1888 |
1889 | @label = new Label
1890 | text: @options.labelText
1891 | fontSize: @options.labelSize
1892 | color: @labelColor
1893 | name: "label"
1894 |
1895 | @helperText = new Label
1896 | fontSize: 12
1897 | text: @options.helperText
1898 | color: @labelColor
1899 | name: "helper Text"
1900 | visible: @options.helperTextVisble
1901 |
1902 | @inputParent = new Layer
1903 | backgroundColor: @options.backgroundColor
1904 | width: @options.width
1905 | height: 28
1906 | name: "input parent"
1907 |
1908 | super @options
1909 |
1910 | @helperText.parent = @line.parent = @inputParent.parent = @
1911 | @helperText.y = 50
1912 | @label.parent = @
1913 | @label.y = 20
1914 | @lineRipple.parent = @line
1915 | @lineRipple.x = Align.center
1916 | @line.y = 44
1917 | @inputParent.y = 10
1918 |
1919 | #------- event --------------------------------------------------------------------------------------------------
1920 |
1921 | @onClick @clicked
1922 | @onTap @clicked
1923 |
1924 | if Utils.isDesktop()
1925 | @onMouseOver @hoverOn
1926 | @onMouseOut @hoverOff
1927 |
1928 | @.on Events.Blur, (value, layer) ->
1929 | @line.height = 1
1930 | @lineRipple.width = 0
1931 | @lineRipple.x = Align.center
1932 | @helperText.color = @labelColor
1933 | @line.backgroundColor = @lineColor
1934 | @options.color = @inputColor
1935 | @label.color = @labelColor
1936 |
1937 | if @.isEmpty
1938 | @label.animate
1939 | properties:
1940 | fontSize: 16
1941 | y: 20
1942 | color: @labelColor
1943 | time: 0.2
1944 |
1945 | #------ Adjust a few things for various types -----------------------------------------------------------------
1946 |
1947 | switch @options.type
1948 | when "search" then @isSearch = true
1949 | when "number" then @isNumber = true
1950 | when "numbers-only", "number-only"
1951 | @isNumber = true
1952 | @options.type = if @options.pattern? then "number" else "text"
1953 | @options.pattern = if @options.pattern? then @options.pattern else PATTERN_NUMBER
1954 |
1955 | @html += switch
1956 | when @isNumber then ""
1957 | when @isSearch then ""
1958 | else ""
1959 |
1960 | if @options.placeHolderColor?
1961 | @html += ""
1962 |
1963 | #------ creating & styling the input -------------------------------------------------------------------------------
1964 |
1965 | @input = document.createElement "input"
1966 |
1967 | @input.type = @options.type
1968 | @input.value = @options.value if @options.value?
1969 | @input.placeholder = @options.placeHolder if @options.placeHolder?
1970 | @input.pattern = @options.pattern if @options.pattern?
1971 | @input.setAttribute("maxLength", @options.maxLength) if @options.maxLength?
1972 | @input.setAttribute("autocapitalize", (if @options.autoCapitalize is true then "on" else "off"))
1973 | @input.setAttribute("autocomplete", (if @options.autoComplete is true then "on" else "off"))
1974 | @input.setAttribute("autocorrect", (if @options.autoCorrect is true then "on" else "off"))
1975 |
1976 | @inputParent._element.appendChild @input
1977 |
1978 | # Setup Values
1979 | @isEmpty = !(@options.value?.length > 0)
1980 | @originalTextColor = @options.color
1981 |
1982 | # Setup Input Style
1983 | inputStyle =
1984 | font: "#{@options.fontWeight} #{@options.fontSize}px/#{@options.lineHeight} #{@options.fontFamily}"
1985 | outline: "none"
1986 | textIndent: "#{@options.indent}px"
1987 | backgroundColor: "transparent"
1988 | height: "22px"
1989 | width: "100%"
1990 | pointerEvents: "none"
1991 | margin: "0"
1992 | padding: "0"
1993 | "-webkit-appearance": "none"
1994 |
1995 | @input.style[key] = val for key, val of inputStyle
1996 | @input.style.color = @options.color if @options.color?
1997 |
1998 |
1999 | @input.onfocus = =>
2000 | document.body.scrollTop = 0
2001 | @input.placeholder = @options.placeHolderFocus if @options.placeHolderFocus?
2002 | document.body.scrollTop = 0
2003 | @emit(Events.Focus, @input.value, @)
2004 |
2005 | @input.onblur = =>
2006 | document.body.scrollTop = 0
2007 | unless @input.placeholder is @options.placeHolder or !@options.placeHolder?
2008 | @input.placeholder = @options.placeHolder
2009 | @emit(Events.Blur, @input.value, @)
2010 |
2011 | @input.oninput = =>
2012 | @isEmpty = !( @input.value?.length > 0)
2013 | @emit(Events.Input, @input.value, @)
2014 |
2015 | @on Events.TouchEnd, -> @input.focus()
2016 | @on "change:color", -> @changeInputTextColor()
2017 |
2018 | @on "keydown", (event) ->
2019 | if event.keyCode is 13
2020 | @line.height = 1
2021 | @lineRipple.width = 0
2022 | @lineRipple.x = Align.center
2023 | @helperText.color = @labelColor
2024 | @line.backgroundColor = @lineColor
2025 | @options.color = @inputColor
2026 | @label.color = @labelColor
2027 |
2028 | if @.isEmpty
2029 | @label.animate
2030 | properties:
2031 | fontSize: 16
2032 | y: 20
2033 | color: @labelColor
2034 | time: 0.2
2035 |
2036 | #------ event functions -------------------------------------------------------------------------------
2037 |
2038 | clear: ->
2039 | @input.value = ""
2040 | @isValid = null
2041 | @isEmpty = true
2042 |
2043 | changeInputTextColor: ->
2044 | @input.style.color = @color.toHexString()
2045 |
2046 | changeInputValue: (v) ->
2047 | @input.value = v
2048 | @input.oninput()
2049 |
2050 | clicked: ->
2051 | @label.animate
2052 | properties:
2053 | fontSize: 12
2054 | y: 0
2055 | color: @options.themeColor
2056 | opacity: @labelFocusOpacity
2057 | time: 0.2
2058 |
2059 | @line.animate
2060 | properties:
2061 | height: 2
2062 | time: 0.2
2063 |
2064 | @lineRipple.animate
2065 | properties:
2066 | width: @options.width
2067 | x: 0
2068 | time: 0.2
2069 |
2070 | hoverOn: ->
2071 | @line.height = 2
2072 | @line.backgroundColor = @lineHoverColor
2073 |
2074 | hoverOff: ->
2075 | @line.height = 1
2076 | @line.backgroundColor = @lineColor
2077 |
2078 |
2079 |
2080 |
2081 |
2082 |
2083 |
2084 |
2085 |
2086 |
2087 | class exports.TextField_Basic extends TextField
2088 |
2089 | constructor: (@options={}) ->
2090 |
2091 | super @options
2092 |
2093 |
2094 |
2095 |
2096 |
2097 | ################################################# 9. TextField_Validation ############################################
2098 | class exports.TextField_Validation extends TextField
2099 |
2100 | constructor: (@options={}) ->
2101 |
2102 | #------- default properties ----------------------------------------------------------------------------------------
2103 | # Make sure we set the Checking Flag
2104 | @shouldCheckValidity = true if @options.pattern? or @options.match?
2105 |
2106 | # Framer Layer Props
2107 | @options.name ?= "password field"
2108 |
2109 | @options.type ?= "password"
2110 | @options.pattern ?= "(?=^.{8,}$)((?=.*\d)|(?=.*\W+))(?![.\n])(?=.*[A-Z])(?=.*[a-z]).*$"
2111 | @options.eyeVisible ?= true
2112 |
2113 | @options.color = @inputColor
2114 |
2115 | if @options.theme is "dark"
2116 | @labelColor = Inputlabel_dark
2117 | else
2118 | @labelColor = Inputlabel_light
2119 |
2120 | @red = "#FF1744"
2121 |
2122 | #text html
2123 | @options.helperText ?= "helperText"
2124 | @options.labelText ?= "Password"
2125 | @options.helperTextVisible ?= false
2126 |
2127 | #Default properties
2128 | _.defaults @options,
2129 | backgroundColor : ""
2130 | width : 200
2131 |
2132 | if @options.pattern is "^(?=.*\d)(?=.*[a-z])(?=.*[A-Z])(?!.*\s).*$"
2133 | @options.helperText ?= "UpperCase, LowerCase and Number"
2134 | else if @options.pattern is "(?=^.{8,}$)((?=.*\d)|(?=.*\W+))(?![.\n])(?=.*[A-Z])(?=.*[a-z]).*$"
2135 | @options.helperText ?= "Must contain 8 characters, 1 uppercase, 1 lowercase, and 1 number/special character"
2136 | else @options.helperText ?= "helperText"
2137 |
2138 | #------- Elements ---------------------------------------------------------------------------------------------------
2139 |
2140 | @errorText = new Label
2141 | fontSize: 12
2142 | text: @options.helperText
2143 | color: @red
2144 | name: "helper Text"
2145 | visible: false
2146 |
2147 | @eyeContianer = new Layer
2148 | width: 22
2149 | height: 22
2150 | backgroundColor: ""
2151 | visible: @options.eyeVisible
2152 | name: "eyeContianer"
2153 |
2154 | @eyeOn = new Layer
2155 | width: 22
2156 | height: 16
2157 | backgroundColor: ""
2158 | visible: false
2159 | name: "eyeOne"
2160 | html: ' '
2161 |
2162 | @eyeOff = new Layer
2163 | width: 23
2164 | height: 19
2165 | backgroundColor: ""
2166 | visible: true
2167 | name: "eyeOff"
2168 | html: ' '
2169 |
2170 | #------- super ---------------------------------------------------------------------------------------------------
2171 |
2172 | super @options
2173 |
2174 | @eyeContianer.parent = @
2175 | @eyeOn.parent = @eyeOff.parent = @eyeContianer
2176 | @eyeContianer.x = @.width - 22
2177 | @eyeContianer.y = 13
2178 | @eyeOn.y = 0
2179 | @errorText.parent = @
2180 | @errorText.y = @helperText.y
2181 |
2182 | #------- event ----------------------------------------------------------------------------------------------------
2183 |
2184 | @onClick @clicked
2185 | @onTap @clicked
2186 |
2187 | if Utils.isDesktop()
2188 | @onMouseOver @hoverOn
2189 | @onMouseOut @hoverOff
2190 |
2191 | eyeOff = @eyeOff
2192 | eyeOn = @eyeOn
2193 |
2194 | @eyeContianer.onClick ->
2195 | if eyeOff.visible is true
2196 | eyeOff.visible = false
2197 | eyeOn.visible = true
2198 | input.type = "text"
2199 | else
2200 | input.type = "password"
2201 | eyeOff.visible = true
2202 | eyeOn.visible = false
2203 |
2204 | @.on Events.Blur, (value, layer) ->
2205 | @label.color = @labelColor
2206 | @line.height = 1
2207 | @lineRipple.width = 0
2208 | @lineRipple.x = Align.center
2209 |
2210 | if @.isEmpty
2211 | @label.animate
2212 | properties:
2213 | fontSize: @options.labelSize
2214 | y: 20
2215 | color: @labelColor
2216 | time: 0.2
2217 | if @helperTextVisible is true
2218 | @helperText.visible = true
2219 | @errorText.visible = false
2220 | else if @isValid
2221 | @line.backgroundColor = @lineColor
2222 | @label.color = @labelColor
2223 | @helperText.color = @labelColor
2224 | if @helperTextVisible is true
2225 | @helperText.visible = true
2226 | @errorText.visible = false
2227 | else
2228 | @line.backgroundColor = @red
2229 | @label.color = @red
2230 |
2231 | @errorText.visible = true
2232 | errorWobble1 = new Animation
2233 | layer: @label
2234 | properties:
2235 | x: 5
2236 | time: 0.05
2237 | errorWobble2 = new Animation
2238 | layer: @label
2239 | properties:
2240 | x: - 5
2241 | time: 0.05
2242 | errorWobble5 = new Animation
2243 | layer: @label
2244 | properties:
2245 | x: 0
2246 | time: 0.025
2247 | errorWobble1.start()
2248 | errorWobble1.onAnimationEnd -> errorWobble2.start()
2249 | errorWobble2.onAnimationEnd -> errorWobble5.start()
2250 | @helperText.visible = false
2251 |
2252 | #------ Adjust a few things for various types --------------------------------------------------------------------
2253 |
2254 | @input.oninput = =>
2255 | @isEmpty = !( @input.value?.length > 0)
2256 | @emit(Events.Input, @input.value, @)
2257 | @checkValidity()
2258 |
2259 | input = @input
2260 |
2261 | checkValidity: ->
2262 | return unless @shouldCheckValidity
2263 |
2264 | if @options.pattern?
2265 | validity = @input.checkValidity()
2266 | @isEmpty = !( @input.value?.length > 0)
2267 |
2268 | if @isValid isnt validity or @isEmpty
2269 | if @isEmpty or !validity
2270 | @isValid = false
2271 | @emit(Events.Invalid, @input.value, @)
2272 | else
2273 | @isValid = true
2274 | @emit(Events.Valid, @input.value, @)
2275 |
2276 | if @checkMatch()
2277 | @isValid = true
2278 | @emit(Events.Match, @input.value, @)
2279 |
2280 | checkMatch: ->
2281 | return false unless @options.match?
2282 | if Array.isArray(@options.match)
2283 | for match in @options.match
2284 | return true if @input.value.indexOf(match) > -1
2285 | else
2286 | return true if @input.value.indexOf(@options.match) > -1
2287 | return false
2288 |
2289 | #--- event functions ----------------------------------------------------------------------------------------------
2290 |
2291 | clicked: ->
2292 | @label.animate
2293 | properties:
2294 | fontSize: 12
2295 | y: - 6
2296 | color: @options.themeColor
2297 | time: 0.2
2298 |
2299 | @line.animate
2300 | properties:
2301 | height: 2
2302 | time: 0.2
2303 |
2304 | @lineRipple.animate
2305 | properties:
2306 | width: @options.width
2307 | x: 0
2308 | time: 0.2
2309 |
2310 | @line.backgroundColor = @lineColor
2311 | @label.color = @themeColor
2312 | @helperText.color = @labelColor
2313 | @errorText.visible = false
2314 | if @options.helperTextVisible is true
2315 | @helperText.visible = true
2316 |
2317 | hoverOn: ->
2318 | @line.height = 2
2319 | @line.backgroundColor = @lineHoverColor
2320 |
2321 | hoverOff: ->
2322 | @line.height = 1
2323 | @line.backgroundColor = @lineColor
2324 |
2325 | eyeClick: ->
2326 | @eye.stateCycle("visible", "visibleOff")
2327 |
2328 |
2329 |
2330 |
2331 |
2332 |
2333 | ################################################# 10. TextArea ######################################################
2334 | class exports.TextArea extends Layer
2335 |
2336 | PATTERN_NUMBER = "[0-9]*"
2337 |
2338 | INPUT_HIDE_PSUEDO_UI = "{ -webkit-appearance: none; display: none; }"
2339 | INPUT_SELECTOR_NUMBER = "input[type=number]::-webkit-inner-spin-button, input[type=number]::-webkit-outer-spin-button"
2340 | INPUT_SELECTOR_SEARCH = "input[type=search]::-webkit-search-cancel-button"
2341 |
2342 | Events.Input = "InputField.OnInput"
2343 | Events.Focus = "InputField.OnFocus"
2344 | Events.Blur = "InputField.OnBlur"
2345 | Events.Valid = "InputField.OnValid"
2346 | Events.Invalid = "InputField.OnInvalid"
2347 | Events.Match = "InputField.OnMatch"
2348 |
2349 | @define "value",
2350 | get: ->
2351 | @textarea.value
2352 |
2353 | set: (v) ->
2354 | return unless v
2355 | if @input
2356 | @changeInputValue v
2357 |
2358 | constructor: (@options={}) ->
2359 |
2360 | #------ default properties -------------------------------------------------------------------------------------------
2361 |
2362 | @isNumber = false
2363 | @isSearch = false
2364 |
2365 | @isEmpty = true
2366 | @isValid = null
2367 | @originalTextColor = null
2368 |
2369 | # Make sure we set the Checking Flag
2370 | @shouldCheckValidity = true if @options.pattern? or @options.match?
2371 |
2372 | # Framer Layer Props
2373 | @options.name ?= "Text area"
2374 | @options.backgroundColor = "rgba(255,255,255,0.01)"
2375 | @options.height ?= 180
2376 |
2377 | # Custom Layer Props
2378 | @options.type ?= "text"
2379 | @options.fontWeight ?= 400
2380 | @options.fontFamily ?= "'Roboto', sans serif"
2381 | @options.indent ?= 0
2382 | @options.placeHolderFocus ?= null
2383 | @options.placeHolderColor ?= null
2384 | @options.width ?= 300
2385 | @options.themeColor ?= "#009688"
2386 | @options.labelText ?= "Type something..."
2387 |
2388 | @options.theme ?= "light"
2389 | theme = @options.theme
2390 |
2391 | #colors
2392 | @options.themeColor ?= "#009688"
2393 |
2394 | themeColor = @options.themeColor
2395 | @red = "#FF1744"
2396 |
2397 | if @options.theme is "dark"
2398 | @labelColor = Inputlabel_dark
2399 | @inputColor = input_dark
2400 | @lineColor = line_dark
2401 | @lineHoverColor = "rgba(255,255,255,1)"
2402 | @labelFocusOpacity = 1
2403 | @lineColor = line_dark
2404 | @options.color = "#fff"
2405 | else
2406 | @labelColor = Inputlabel_light
2407 | @inputColor = input_light
2408 | @lineColor = line_light
2409 | @lineHoverColor = "rgba(0,0,0,0.87)"
2410 | @labelFocusOpacity = 0.87
2411 | @lineColor = line_light
2412 | @options.color = "rgba(0,0,0,0.87)"
2413 |
2414 | @options.color = @inputColor
2415 |
2416 | if Utils.isMobile()
2417 | @options.fontSize ?= 16 * 2
2418 | @options.lineHeight ?= 24 * 2
2419 | @options.style =
2420 | "padding" : "56px 32px 32px 32px"
2421 | else
2422 | @options.fontSize ?= 16
2423 | @options.lineHeight ?= 24
2424 | @options.style =
2425 | "padding" : "28px 16px 16px 16px"
2426 |
2427 | @options.labelSize ?= 16
2428 |
2429 | #text styling
2430 | Utils.insertCSS('@import url(https://fonts.googleapis.com/css?family=Roboto);')
2431 |
2432 | @options.fontFamily ?= "'Roboto', sans serif"
2433 | @options.fontWeight ?= 400
2434 | @options.letterSpacing ?= 0
2435 | @options.limitOn ?= true
2436 |
2437 | if @options.limitOn is false
2438 | @options.characterLimit = 1000000000000
2439 | else @options.characterLimit ?= 200
2440 |
2441 | #------- Elements --------------------------------------
2442 |
2443 | @label = new Label
2444 | text: @options.labelText
2445 | fontSize: @options.labelSize
2446 | color: @labelColor
2447 | name: "label"
2448 | name: "label"
2449 |
2450 | @limit = new Layer
2451 | html: "0 / " + @options.characterLimit
2452 | backgroundColor: ""
2453 | width: 100
2454 | height: 12
2455 | visible: @options.limitOn
2456 | name: "limit"
2457 | @limit.style =
2458 | color: @labelColor
2459 | fontFamily: @options.fontFamily
2460 | fontSize: "12px"
2461 | lineHeight: "12px"
2462 | textAlign: "right"
2463 | letterSpacing: @options.letterSpacing
2464 |
2465 | @errorText = new Label
2466 | fontSize: 12
2467 | color: @red
2468 | name: "error text"
2469 | visible: false
2470 | text: "Exeeds text limit."
2471 |
2472 | @border = new Layer
2473 | width: @options.width
2474 | height: @options.height
2475 | backgroundColor: ""
2476 | borderWidth: 1
2477 | borderColor: @lineColor
2478 | borderRadius: 2
2479 | name: "border"
2480 |
2481 | #------ super -----------------------------------------------------------------------------------------------------
2482 |
2483 | super @options
2484 |
2485 | @label.parent = @border.parent = @
2486 | @limit.parent = @
2487 | @errorText.parent = @
2488 | @label.y = 20
2489 | @label.x = 16
2490 | @limit.x = @width - 100
2491 | @limit.y = @height + 8
2492 | @errorText.y = @height + 8
2493 |
2494 | #------- event -----------------------------------------------------------------------------------------------------
2495 |
2496 | @onClick @clicked
2497 |
2498 | @.on Events.Blur, (value, layer) ->
2499 | @blurred()
2500 |
2501 | @.on Events.Focus, (value, layer) ->
2502 | @focus()
2503 |
2504 | if Utils.isDesktop()
2505 | @.onMouseOver @hoverOn
2506 | @.onMouseOut @hoverOff
2507 |
2508 | @.on Events.Input, (value, layer) ->
2509 | @limit.html = @value.length + " / " + @options.characterLimit
2510 | if @value.length > @options.characterLimit
2511 | @errorText.visible = true
2512 | @limit.color = @red
2513 | @border.borderColor = @red
2514 | @label.color = @red
2515 | else
2516 | @errorText.visible = false
2517 | @limit.color = @labelColor
2518 | @border.borderColor = @options.themeColor
2519 | @label.color = @options.themeColor
2520 |
2521 | #------- Adjust a few things for various types --------------------------------------------------------------------
2522 |
2523 | switch @options.type
2524 | when "search" then @isSearch = true
2525 | when "number" then @isNumber = true
2526 | when "numbers-only", "number-only"
2527 | @isNumber = true
2528 | @options.type = if @options.pattern? then "number" else "text"
2529 | @options.pattern = if @options.pattern? then @options.pattern else PATTERN_NUMBER
2530 |
2531 | @html += switch
2532 | when @isNumber then ""
2533 | when @isSearch then ""
2534 | else ""
2535 |
2536 | if @options.placeHolderColor?
2537 | @html += ""
2538 |
2539 | #------- create input -------------------------------------------------------------------------------------------
2540 |
2541 | @textarea = document.createElement "textarea"
2542 |
2543 | @textarea.value = @options.value if @options.value?
2544 | @input.placeholder = @options.placeHolder if @options.placeHolder?
2545 | @textarea.setAttribute("maxLength", @options.maxLength) if @options.maxLength?
2546 | @textarea.setAttribute("autocapitalize", (if @options.autoCapitalize is true then "on" else "off"))
2547 | @textarea.setAttribute("autocomplete", (if @options.autoComplete is true then "on" else "off"))
2548 | @textarea.setAttribute("autocorrect", (if @options.autoCorrect is true then "on" else "off"))
2549 |
2550 | @_element.appendChild @textarea
2551 |
2552 | # Setup Values
2553 | @isEmpty = !(@options.value?.length > 0)
2554 | @originalTextColor = @options.color
2555 |
2556 | # Setup Input Style
2557 |
2558 | @_textAreaStyle =
2559 | fontSize: "#{@options.fontSize}px"
2560 | lineHeight: "#{@options.lineHeight}px"
2561 | fontWeight: "#{@options.fontWeight}"
2562 | fontFamily: "#{@options.fontFamily}"
2563 | outline: "none"
2564 | textIndent: "#{@options.indent}px"
2565 | backgroundColor: "transparent"
2566 | height: "100%"
2567 | width: "100%"
2568 | pointerEvents: "none"
2569 | margin: "0"
2570 | overflow: "hidden"
2571 | resize: "none"
2572 | "-webkit-appearance": "none"
2573 |
2574 | @textarea.style[key] = val for key, val of @_textAreaStyle
2575 | @textarea.style.color = @options.color if @options.color?
2576 |
2577 | @textarea.onfocus = =>
2578 | document.body.scrollTop = 0
2579 | @input.placeholder = @options.placeHolderFocus if @options.placeHolderFocus?
2580 | document.body.scrollTop = 0
2581 | @emit(Events.Focus, @textarea.value, @)
2582 |
2583 | @textarea.onblur = =>
2584 | document.body.scrollTop = 0
2585 | unless @textarea.placeholder is @options.placeHolder or !@options.placeHolder?
2586 | @input.placeholder = @options.placeHolder
2587 | @emit(Events.Blur, @textarea.value, @)
2588 |
2589 | @_textAreaStyleonblur = =>
2590 | document.body.scrollTop = 0
2591 | unless @input.placeholder is @options.placeHolder or !@options.placeHolder?
2592 | @input.placeholder = @options.placeHolder
2593 | @emit(Events.Blur, @input.value, @)
2594 |
2595 | @textarea.oninput = =>
2596 | @isEmpty = !( @textarea.value?.length > 0)
2597 | @emit(Events.Input, @textarea.value, @)
2598 | @checkValidity()
2599 |
2600 | @on Events.TouchEnd, -> @textarea.focus()
2601 | @on "change:color", -> @changeInputTextColor()
2602 |
2603 | #Update the height whenever anything changes.
2604 | @textarea.onkeydown = => @_update()
2605 | @textarea.onkeyup = => @_update()
2606 | @textarea.change = => @_update()
2607 | _resizeParent = (layer, parentMinHeight, bottomPadding) ->
2608 | # Variable for parent
2609 | layerParent = layer.parent
2610 |
2611 | # Array to store all children's maxYs
2612 | allChildrenMaxYs = []
2613 |
2614 | # Push each maxY to an array
2615 | for max in layerParent.children
2616 | allChildrenMaxYs.push(max.maxY)
2617 |
2618 | # Find the bottom-most maxY value
2619 | tallestChildMaxY = Math.max.apply(null, allChildrenMaxYs)
2620 |
2621 | # Store the distance between the bottom of that and the parent layer
2622 | layerParent.height = Math.max(tallestChildMaxY + bottomPadding, parentMinHeight)
2623 |
2624 | # TODO - Maintain the bottom padding of the parent.
2625 |
2626 | # Reflow all the siblings under the text layer
2627 | _reflowSiblings = (layer, layerMaxY) ->
2628 | layerList = layer.parent.children
2629 | for a in [layerList.indexOf(layer)+1...layerList.length]
2630 | yDiff = layerList[a].y - layerMaxY
2631 | layerList[a].y = layer.maxY + yDiff
2632 | # TODO - redo this without the assumption that all siblings after the layer are below it.
2633 |
2634 | # Update height function
2635 | _update: =>
2636 | setTimeout =>
2637 | layerMaxY = @.maxY
2638 | # Add back any line breaks that the value method gets ride of
2639 | _trueValue = @textarea.value.replace(//g, ">").replace(/&/g, "&").replace(/\n/g, " ");
2640 |
2641 | # If it's empty, make sure there's a letter in there to calculate *something*
2642 | if _trueValue.trim() == "" then _trueValue = "a"
2643 |
2644 | # Calculate the height!!!
2645 | calcHeight = Utils.round(Utils.textSize(_trueValue, @_textAreaStyle, {width: @.width}).height, 0)
2646 |
2647 | # Set the height to either the calculated height, or the minHeight, whichever is greater.
2648 | @.height = Math.max(calcHeight, @options.minHeight)
2649 | if @options.reflowSiblings == true then _reflowSiblings(@, layerMaxY)
2650 | if @options.resizeParent == true then _resizeParent(@, @parentOgHeight, @options.parentBottomPadding)
2651 |
2652 | #------- event functions -------------------------------------------------------------------------------------------
2653 |
2654 | checkValidity: ->
2655 | return unless @shouldCheckValidity
2656 |
2657 | clear: ->
2658 | @input.value = ""
2659 | @isValid = null
2660 | @isEmpty = true
2661 |
2662 | changeInputTextColor: ->
2663 | @input.style.color = @color.toHexString()
2664 |
2665 | changeInputValue: (v) ->
2666 | @input.value = v
2667 | @input.oninput()
2668 |
2669 | clicked: ->
2670 | @label.animate
2671 | properties:
2672 | fontSize: 12
2673 | y: 8
2674 | color: @options.themeColor
2675 | x: 16
2676 | time: 0.2
2677 | @border.borderColor = @options.themeColor
2678 | @border.borderWidth = 2
2679 |
2680 | error: ->
2681 | @borderColor = @red
2682 |
2683 | focus: ->
2684 | @label.fontSize = 12
2685 | @borderColor = @options.themeColor
2686 | @border.borderWidth = 2
2687 | @label.color = @labelColor
2688 |
2689 | hoverOn: ->
2690 | @border.borderWidth = 2
2691 | @options.borderColor = @lineHoverColor
2692 |
2693 | hoverOff: ->
2694 | @border.borderWidth = 1
2695 | @borderColor = @lineColor
2696 |
2697 | blurred: (value, layer) ->
2698 | @label.color = @labelColor
2699 | @border.borderColor = @lineColor
2700 |
2701 | if @.isEmpty
2702 | @label.animate
2703 | properties:
2704 | fontSize: 16
2705 | y: 20
2706 | x: 16
2707 | color: @labelColor
2708 | time: 0.2
2709 | @border.borderColor = @labelColor
2710 |
2711 | if @value.length > @options.characterLimit
2712 | @errorText.visible = true
2713 | @limit.color = @red
2714 | @border.borderColor = @red
2715 | @label.color = @red
2716 |
2717 | @border.borderWidth = 1
2718 |
2719 |
2720 |
2721 |
2722 |
2723 |
2724 | ################################################# 11. TextField_Dropdown ############################################
2725 | class exports.TextField_Dropdown extends Layer
2726 | constructor: (@options={}) ->
2727 |
2728 | #------ default properties ------------------------------------------------------------------------------------------
2729 | if @options.theme is "dark"
2730 | @options.screenColor ?= "#000"
2731 |
2732 | @options.choices ?= ["apple", "banana", "blueberry","cantaloupe", "cherry","coconut", "fig", "grape","grapefruit","guava", "kiwifruit", "lemon","lime", "lychee", "mango", "melon", "orange","papaya", "passionfruit", "peach", "pear","pineapple", "plum","pomegranate", "raspberry", "strawberry", "watermelon"]
2733 | @options.labelText ?= "Select a fruit"
2734 | @options.theme ?= "light"
2735 | @options.visibleItems ?= 4
2736 | @options.activeSelection ?= null
2737 |
2738 | #colors
2739 | @options.themeColor ?= "#009688"
2740 | themeColor = @themeColor
2741 |
2742 | if @options.theme is "dark"
2743 | @labelColor = label_dark
2744 | @lineColor = line_dark
2745 | @lineHoverColor = line_dark_hover
2746 | @inputColor = input_dark
2747 | else
2748 | @labelColor = label_light
2749 | @lineColor = line_light
2750 | @lineHoverColor = line_light_hover
2751 | @inputColor = input_light
2752 |
2753 | _.defaults @options,
2754 | backgroundColor : ""
2755 | height: 50
2756 | color: "#E91E63"
2757 | width : 150
2758 | name: "DropDown"
2759 |
2760 | #------ label -------------------------------------------------------------------------------------------------
2761 |
2762 | @label = new Label
2763 | text: @options.labelText
2764 | color: @labelColor
2765 | name: "label"
2766 | fontSize: 12
2767 | visible: false
2768 |
2769 | @placeHolder = new Label
2770 | text: @options.labelText
2771 | color: @inputColor
2772 | y: 20
2773 | name: "label"
2774 |
2775 | #------ arrow -----------------------------------------------------------------------------------------------
2776 |
2777 | @arrow = new Layer
2778 | html: ' '
2779 | size: 24
2780 | backgroundColor: ""
2781 | color: "#555"
2782 | width:10
2783 | height: 5
2784 | name:"Arrow"
2785 |
2786 | #------ line ---------------------------------------------------------------------------------------------------
2787 |
2788 | @line = new Layer
2789 | height: 1
2790 | width: @options.width
2791 | y: 49
2792 | backgroundColor: @lineColor
2793 | name: "line"
2794 |
2795 | #------ container -----------------------------------------------------------------------------------------------
2796 |
2797 | @container = new Layer
2798 | width: @options.width
2799 | borderRadius: 2
2800 | backgroundColor: "#fff"
2801 | height: @options.visibleItems * 50 + 20
2802 | clip: true
2803 | name: "container"
2804 |
2805 | #------ super ---------------------------------------------------------------------------------------------------
2806 |
2807 | super @options
2808 |
2809 | @container.states =
2810 | open:
2811 | height: @options.visibleItems * 50 + 20
2812 | y: 0
2813 | closed:
2814 | height: 0
2815 | y: 50
2816 | @container.states.switchInstant "closed"
2817 | @container.animationOptions = time: 0.5
2818 |
2819 | @label.parent = @
2820 | @placeHolder.parent = @
2821 | @container.parent = @arrow.parent = @line.parent = @
2822 |
2823 | @arrow.y = Align.center(2)
2824 | @arrow.x = @options.width - 24
2825 | @container.y = 50
2826 |
2827 | placeHolder = @placeHolder
2828 | label = @label
2829 | container = @container
2830 | activeSelection = @activeSelection
2831 | labelColor = @labelColor
2832 |
2833 | #------ shadows -------------------------------------------------------------------------------------------------
2834 |
2835 | shadow = new Shadow
2836 | parent: @
2837 | height: @options.visibleItems * 50 + 20
2838 | width: @width
2839 | borderRadius: @container.borderRadius
2840 | y: 0
2841 | name: "shadows"
2842 |
2843 | for item in shadow.array
2844 | item.states.open =
2845 | y: 0
2846 | height: @options.visibleItems * 50 + 20
2847 | item.states.closed =
2848 | height: 0
2849 | y: 50
2850 |
2851 | item.animationOptions = time: 0.5
2852 |
2853 | item.states.switchInstant "_2dp"
2854 | item.states.switchInstant "closed"
2855 |
2856 | #------ scroll area ------------------------------------------------------------------------------------------
2857 |
2858 | container_ScrollArea = new ScrollComponent
2859 | parent: @container
2860 | width: @container.width
2861 | backgroundColor: ""
2862 | height: @options.visibleItems * 50 + 20
2863 | name: "scrollArea"
2864 | container_ScrollArea.content.draggable.overdrag = false
2865 | container_ScrollArea.content.draggable.bounce = false
2866 | container_ScrollArea.mouseWheelEnabled = true
2867 |
2868 | #------ slider ------------------------------------------------------------------------------------------
2869 |
2870 | slider = new SliderComponent
2871 | width: 5
2872 | height: container_ScrollArea.height - 30
2873 | y: 15
2874 | borderRadius: 0
2875 | parent: container_ScrollArea
2876 | x: container_ScrollArea.width - 5
2877 | backgroundColor: ""
2878 | min: 0
2879 | max: (@options.choices.length * 50) - 200
2880 | value: -15
2881 | name: slider
2882 | slider.fill.backgroundColor = ""
2883 |
2884 | slider.knob.backgroundColor = "BDBDBD"
2885 | slider.knob.shadowY = 0
2886 | slider.knob.shadowSpread = 0
2887 | slider.knob.shadowBlur = 0
2888 | slider.knob.borderRadius = 1
2889 | slider.knob.width = 5
2890 | slider.knob.height = 30
2891 |
2892 | slider.on "change:value", ->
2893 | container_ScrollArea.content.y = - this.value
2894 |
2895 | container_ScrollArea.onMove ->
2896 | slider.value = container_ScrollArea.scrollY
2897 |
2898 | #------ choice loop ------------------------------------------------------------------------------------------
2899 |
2900 | as = null
2901 |
2902 | for i in [0...@options.choices.length]
2903 | choice = new Layer
2904 | parent: container_ScrollArea.content
2905 | width: container_ScrollArea.width
2906 | height: 50
2907 | y: 50 * i + 10
2908 | backgroundColor: ""
2909 | name: "choice"
2910 |
2911 | choice_label = new Label
2912 | text: @options.choices[i]
2913 | parent: choice
2914 | x: 20
2915 | y: Align.center
2916 | name: @options.choices[i] + "label"
2917 | color: label_light
2918 |
2919 | choice.onMouseOver ->
2920 | this.backgroundColor = "#eee"
2921 |
2922 | choice.onMouseOut ->
2923 | this.backgroundColor = "#fff"
2924 |
2925 | choice.onClick ->
2926 | as = this.children[0].text
2927 | placeHolder.text = this.children[0].text
2928 | placeHolder.color = labelColor
2929 | container.states.switch "closed"
2930 | label.visible = true
2931 | for item in shadow.array
2932 | item.states.switch "closed"
2933 |
2934 | container = @container
2935 |
2936 | #------ events ---------------------------------------------------------------------------------------------------
2937 |
2938 | @onClick ->
2939 | for item in shadow.array
2940 | item.states.switch "open"
2941 | container.states.switch "open"
2942 | @activeSelection = as
2943 |
2944 | if Utils.isDesktop()
2945 | @onMouseOver @hoverOn
2946 | @onMouseOut @hoverOff
2947 |
2948 | #------event function ---------------------------------------------------------------------------------------------
2949 |
2950 | hoverOn: ->
2951 | @line.height = 2
2952 | @line.backgroundColor = @lineHoverColor
2953 |
2954 | hoverOff: ->
2955 | @line.height = 1
2956 | @line.backgroundColor = @lineColor
2957 |
2958 | #------ getters and setters -----------------------------------------------------------------------------------------
2959 |
2960 | @define 'color',
2961 | get: ->
2962 | @options.color
2963 | set: (value) ->
2964 | @options.color = value
2965 |
2966 | @define 'choices',
2967 | get: ->
2968 | @options.choices
2969 | set: (value) ->
2970 | @options.choices = value
2971 |
2972 | @define 'activeSelection',
2973 | get: ->
2974 | @options.activeSelection
2975 | set: (value) ->
2976 | @options.activeSelection = value
2977 |
2978 |
2979 |
2980 |
2981 |
2982 |
2983 | ################################################## 12. AppBar ########################################################
2984 | class exports.AppBar extends Layer
2985 |
2986 | constructor: (@options={}) ->
2987 |
2988 | #------ default properties ------------------------------------------------------------------------------------------
2989 |
2990 | @options.width ?= Screen.width
2991 | @options.labelText ?= "Form"
2992 | @options.fontSize ?= 22
2993 | @options.fontWeight ?= 500
2994 | @options.fontFamily ?= "'Roboto', sans serif"
2995 | @options.labelColor = "#fff"
2996 | @options.themeColor ?= "#009688"
2997 | @options.backgroundColor ?= @options.themeColor
2998 | @options.mobile ?= false
2999 | @options.menuIconVisble ?= true
3000 | @options.name ?= "app bar"
3001 | @options.statusIconsY ?= Align.center(-8)
3002 | @options.menuIconY ?= Align.center()
3003 |
3004 | #------ elements -------------------------------------------------------------------------------------------------
3005 |
3006 | @appCont = new Layer
3007 | height: 56
3008 | width: @options.width
3009 | backgroundColor: ""
3010 | name: "app bar contianer"
3011 |
3012 | if Utils.isMobile() or @options.mobile is true
3013 | @statusBar = new Layer
3014 | width: @options.width
3015 | height: 24
3016 | backgroundColor: "rgba(0,0,0,0.30)"
3017 | name: "status bar"
3018 | @options.height ?= 80
3019 | @appCont.y = 24
3020 | else
3021 | @options.height ?= 56
3022 |
3023 | @menuIcon = new Layer
3024 | size: 48
3025 | backgroundColor: ""
3026 | visible: @options.menuIconVisble
3027 | name: "menu icon"
3028 |
3029 | @title = new TextLayer
3030 | text: @options.labelText
3031 | fontSize: @options.fontSize
3032 | fontFamily: @options.fontFamily
3033 | color: @options.labelColor
3034 | fontWeight: @options.fontWeight
3035 | name: "title"
3036 |
3037 | #------ super -------------------------------------------------------------------------------------------------
3038 |
3039 | super @options
3040 |
3041 | shadow = new Shadow
3042 | width: @width
3043 | height: @height
3044 | name: "shadows"
3045 |
3046 | shadow.parent = @
3047 | @title.parent = @
3048 | @title.y = Align.center()
3049 | @title.x = 16
3050 | @appCont.parent = @
3051 | @menuIcon.parent = @title.parent = @appCont
3052 | @menuIcon.x = 16
3053 | @menuIcon.y = @options.menuIconY
3054 |
3055 | if @menuIcon.visible is true
3056 | @title.x = 48 + 16 + 16
3057 |
3058 | #------ menu icon -------------------------------------------------------------------------------------------------
3059 |
3060 |
3061 | menuIcon = new Layer
3062 | html: ' '
3063 | width: 18
3064 | height: 12
3065 | parent: @menuIcon
3066 | x: Align.center()
3067 | y: Align.center()
3068 | backgroundColor: ""
3069 | name: "icon"
3070 |
3071 | #------ status bar -------------------------------------------------------------------------------------------------
3072 |
3073 | if Utils.isMobile() or @options.mobile is true
3074 | @statusBar.parent = @
3075 | @title.y = Align.center(10)
3076 |
3077 | statusBarTime = new TextLayer
3078 | fontSize: 13
3079 | parent: @statusBar
3080 | y: Align.center
3081 | x: @width - 55
3082 | color : "#fff"
3083 | fontFamily: "'Roboto', sans serif"
3084 | textAlign: "right"
3085 | name: "status bar time"
3086 |
3087 | setTime = () ->
3088 | date = new Date
3089 | minute = date.getMinutes()
3090 | hour = date.getHours()
3091 |
3092 | zone = "AM"
3093 |
3094 | if hour < 10
3095 | hour = '0' + hour
3096 |
3097 | if hour > 12
3098 | hour = hour - 12
3099 | zone = "PM"
3100 | else
3101 | zone = "AM"
3102 |
3103 | if minute < 10
3104 | minute = '0' + minute
3105 |
3106 | statusBarTime.text = "#{hour}:#{minute} #{zone}"
3107 |
3108 | Utils.delay 30, ->
3109 | setTime()
3110 |
3111 | setTime()
3112 |
3113 | statusIcons = new Layer
3114 | name: "status icons"
3115 | parent: @statusBar
3116 | html: ' '
3117 | backgroundColor: ""
3118 | width: 53
3119 | height: 16
3120 | y: @options.statusIconsY
3121 | x: @width - statusBarTime.width - 70
3122 |
3123 | @title.y = Align.center
3124 |
3125 | #------ on resize -------------------------------------------------------------------------------------------------
3126 |
3127 | at = @
3128 | statusBar = @statusBar
3129 | isMob = @options.mobile
3130 |
3131 | window.onresize = ->
3132 | at.width = Screen.width
3133 | shadow.umbra.width = Screen.width
3134 | shadow.ambient.width = Screen.width
3135 | shadow.penumbra.width = Screen.width
3136 | if Utils.isMobile() or isMob is true
3137 | statusBar.width = Screen.width
3138 | statusBarTime.x = Screen.width - 55
3139 | statusIcons.x = Screen.width - statusBarTime.width - 68
3140 |
3141 |
3142 |
3143 |
3144 |
3145 |
3146 |
3147 |
3148 |
3149 |
3150 |
3151 |
3152 |
3153 |
3154 |
3155 |
3156 |
3157 |
3158 |
3159 |
3160 |
3161 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # MaterialComponents version 1
2 |
3 | Easily create, use and modify various Material Design components using this simple module. All of the components are design according to eh Material Design Guidelines — hopefully making your prototyping life a little easier.
4 |
5 | — FULL DISCLOSURE —
6 | 1. While I tried to follow the Material Design guidelines as closely as possible — I probably made a mistake here or there where it doesn’t follow the guidelines exactly.
7 | 2. This is my first module that I have shared — and there are still lots (x100) of bugs, especially where icons are involved.
8 |
9 | This version contains
10 | 1. Color
11 | 2. FlatButton
12 | 3. RaisedButton
13 | 4. FAB
14 | 5. Checkboxes
15 | 6. Radio Buttons
16 | 7. Switch
17 | 8. TextField (frankenstiend from Jordan Robert Dobson's InputField)
18 | 9. TextField_Validation (frankenstiend from Jordan Robert Dobson's InputField)
19 | 10. TextArea (frankenstiend from Jordan Robert Dobson's InputField and Blaine Billingsley's Autogrow)
20 | 11. TextField_Dropdown
21 | 12. AppBar
22 |
23 | installation:
24 | 1. put the MaterialComponents.coffee in the 'modules' folder of your prototype.
25 | 2. in your prototype in Framer, add: MaterialComponents = require 'MaterialComponents'
26 | 3. create components by just going: button = new MaterialComponents.RaisedButton
27 |
28 | Enjoy! and let me know if you find any bugs, x
29 |
30 |
--------------------------------------------------------------------------------