├── .editorconfig
├── .gitignore
├── Gruntfile.js
├── README.md
├── bower.json
├── dev
├── spreadIt.css
└── spreadit.js
├── dist
├── spreadIt.css
├── spreadit.js
└── spreadit.min.js
├── example
├── index.html
├── sample.csv
└── sample.xlsx
├── fonts
└── arrows
│ ├── select-arrows.svg
│ ├── select-arrows.ttf
│ └── select-arrows.woff
├── importer-screenshot.png
├── package.json
├── screenshot.png
└── src
├── columnManager.html
├── dropzone.html
├── module.js
├── sass
├── _columnManager.scss
├── _dropzone.scss
├── bourbon
│ ├── _bourbon-deprecated-upcoming.scss
│ ├── _bourbon.scss
│ ├── addons
│ │ ├── _border-color.scss
│ │ ├── _border-radius.scss
│ │ ├── _border-style.scss
│ │ ├── _border-width.scss
│ │ ├── _buttons.scss
│ │ ├── _clearfix.scss
│ │ ├── _ellipsis.scss
│ │ ├── _font-stacks.scss
│ │ ├── _hide-text.scss
│ │ ├── _margin.scss
│ │ ├── _padding.scss
│ │ ├── _position.scss
│ │ ├── _prefixer.scss
│ │ ├── _retina-image.scss
│ │ ├── _size.scss
│ │ ├── _text-inputs.scss
│ │ ├── _timing-functions.scss
│ │ ├── _triangle.scss
│ │ └── _word-wrap.scss
│ ├── css3
│ │ ├── _animation.scss
│ │ ├── _appearance.scss
│ │ ├── _backface-visibility.scss
│ │ ├── _background-image.scss
│ │ ├── _background.scss
│ │ ├── _border-image.scss
│ │ ├── _calc.scss
│ │ ├── _columns.scss
│ │ ├── _filter.scss
│ │ ├── _flex-box.scss
│ │ ├── _font-face.scss
│ │ ├── _font-feature-settings.scss
│ │ ├── _hidpi-media-query.scss
│ │ ├── _hyphens.scss
│ │ ├── _image-rendering.scss
│ │ ├── _keyframes.scss
│ │ ├── _linear-gradient.scss
│ │ ├── _perspective.scss
│ │ ├── _placeholder.scss
│ │ ├── _radial-gradient.scss
│ │ ├── _selection.scss
│ │ ├── _text-decoration.scss
│ │ ├── _transform.scss
│ │ ├── _transition.scss
│ │ └── _user-select.scss
│ ├── functions
│ │ ├── _assign-inputs.scss
│ │ ├── _contains-falsy.scss
│ │ ├── _contains.scss
│ │ ├── _is-length.scss
│ │ ├── _is-light.scss
│ │ ├── _is-number.scss
│ │ ├── _is-size.scss
│ │ ├── _modular-scale.scss
│ │ ├── _px-to-em.scss
│ │ ├── _px-to-rem.scss
│ │ ├── _shade.scss
│ │ ├── _strip-units.scss
│ │ ├── _tint.scss
│ │ ├── _transition-property-name.scss
│ │ └── _unpack.scss
│ ├── helpers
│ │ ├── _convert-units.scss
│ │ ├── _directional-values.scss
│ │ ├── _font-source-declaration.scss
│ │ ├── _gradient-positions-parser.scss
│ │ ├── _linear-angle-parser.scss
│ │ ├── _linear-gradient-parser.scss
│ │ ├── _linear-positions-parser.scss
│ │ ├── _linear-side-corner-parser.scss
│ │ ├── _radial-arg-parser.scss
│ │ ├── _radial-gradient-parser.scss
│ │ ├── _radial-positions-parser.scss
│ │ ├── _render-gradients.scss
│ │ ├── _shape-size-stripper.scss
│ │ └── _str-to-num.scss
│ └── settings
│ │ ├── _asset-pipeline.scss
│ │ ├── _prefixer.scss
│ │ └── _px-to-em.scss
└── spreadIt.scss
├── siColumnManager.directive.js
├── siDropZone.directive.js
├── siTrigger.directive.js
└── spreadIt.service.js
/.editorconfig:
--------------------------------------------------------------------------------
1 | # http://editorconfig.org
2 | root = true
3 |
4 | [*]
5 | indent_style = space
6 | indent_size = 4
7 | end_of_line = lf
8 | charset = utf-8
9 | trim_trailing_whitespace = true
10 | insert_final_newline = false
11 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | # Created by .ignore support plugin (hsz.mobi)
2 | ### Node template
3 | # Logs
4 | logs
5 | *.log
6 | npm-debug.log*
7 |
8 | # Runtime data
9 | pids
10 | *.pid
11 | *.seed
12 |
13 | # Directory for instrumented libs generated by jscoverage/JSCover
14 | lib-cov
15 |
16 | # Coverage directory used by tools like istanbul
17 | coverage
18 |
19 | # Grunt intermediate storage (http://gruntjs.com/creating-plugins#storing-task-files)
20 | .grunt
21 |
22 | # node-waf configuration
23 | .lock-wscript
24 |
25 | # Compiled binary addons (http://nodejs.org/api/addons.html)
26 | build/Release
27 |
28 | # Dependency directories
29 | node_modules
30 | jspm_packages
31 |
32 | # Optional npm cache directory
33 | .npm
34 |
35 | # Optional REPL history
36 | .node_repl_history
37 |
38 | bower_components/
39 | .tmp/
40 | .sass-cache/
41 |
42 |
--------------------------------------------------------------------------------
/Gruntfile.js:
--------------------------------------------------------------------------------
1 | module.exports = function(grunt) {
2 |
3 | require('load-grunt-tasks')(grunt);
4 |
5 | // Project configuration.
6 | grunt.initConfig({
7 |
8 | pkg: grunt.file.readJSON('package.json'),
9 | concurrent: {
10 | example: {
11 | tasks: ['serve', 'watch:dev', 'open:example'],
12 | options: {
13 | logConcurrentOutput: true
14 | }
15 | }
16 | },
17 | open: {
18 | example: {
19 | url: 'http://localhost:9099/example/index.html'
20 | }
21 | },
22 | copy: {
23 | dist: {
24 | expand: true,
25 | cwd: 'src',
26 | dest: 'dist',
27 | src: ['images/**/*']
28 | },
29 | dev: {
30 | expand: true,
31 | cwd: 'src',
32 | dest: 'dev',
33 | src: ['images/**/*']
34 | }
35 | },
36 | ngtemplates: {
37 | all: {
38 | options: {
39 | module: 'bg.spreadit',
40 | prefix: '/',
41 | htmlmin: {
42 | collapseWhitespace: true,
43 | keepClosingSlash: true
44 | }
45 | },
46 | cwd: 'src',
47 | src: '**/*.html',
48 | dest: '.tmp/spreadit.templates.js'
49 | }
50 | },
51 | clean: {
52 | dist: ['.tmp', 'dist'],
53 | dev: ['.tmp', 'dev']
54 | },
55 | concat: {
56 | dist: {
57 | src: ['src/module.js', 'src/**/*.js', '.tmp/**/*.js'],
58 | dest: 'dist/spreadit.js'
59 | },
60 | dev: {
61 | src: ['src/module.js', 'src/**/*.js', '.tmp/**/*.js'],
62 | dest: 'dev/spreadit.js'
63 | }
64 | },
65 | uglify: {
66 | dist: {
67 | files: {
68 | 'dist/spreadit.min.js': ['dist/spreadit.js']
69 | }
70 | }
71 | },
72 | sass: {
73 | options: {
74 | style: 'compressed',
75 | sourcemap: 'none'
76 | },
77 | dist: {
78 | expand: true,
79 | cwd: 'src/sass',
80 | src: ['**/*.scss'],
81 | dest: 'dist',
82 | ext: '.css'
83 | },
84 | dev: {
85 | expand: true,
86 | cwd: 'src/sass',
87 | src: ['**/*.scss'],
88 | dest: 'dev',
89 | ext: '.css'
90 | }
91 | },
92 | watch: {
93 | dev: {
94 | files: ['src/**/*', 'example/**/*'],
95 | tasks: 'dev',
96 | options: {
97 | livereload: false
98 | }
99 | }
100 | },
101 | serve: {
102 | options: {
103 | port: 9099
104 | }
105 | }
106 | });
107 |
108 | grunt.registerTask('build', [
109 | 'clean:dist',
110 | 'copy:dist',
111 | 'ngtemplates',
112 | 'concat:dist',
113 | 'uglify',
114 | 'sass:dist'
115 | ]);
116 |
117 | grunt.registerTask('dev', [
118 | 'clean:dev',
119 | 'copy:dev',
120 | 'ngtemplates',
121 | 'concat:dev',
122 | 'sass:dev'
123 | ]);
124 |
125 | grunt.registerTask('example', [
126 | 'clean:dev',
127 | 'copy:dev',
128 | 'ngtemplates',
129 | 'concat:dev',
130 | 'sass:dev',
131 | 'concurrent:example'
132 | ]);
133 |
134 |
135 | };
136 |
137 |
138 |
139 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # Spreadit - Spreadsheet data importing simplified and 100% in the browser.
2 |
3 | Spreadit is an angular directive inspired by the guys at [Conference Badge](https://www.conferencebadge.com/). It imports data from Excel or CSV as JSON so it
4 | can be used in the browser or uploaded to the server. It supports header and column detection. Users can also rename and ignore columns before importing the data.
5 |
6 | 
7 | 
8 |
9 | ## Install It
10 | * **Manual**: download latest from [here](https://github.com/blakgeek/spreadit/releases/latest)
11 | * **Bower**: `bower install spreadit --save`
12 | * **NPM**: `npm install spreadit`
13 |
14 | ## See It In Action
15 | * [Basic Example](https://jsfiddle.net/blakgeek/vumyL0x1/show)
16 | * [Configure Columns](https://jsfiddle.net/blakgeek/q50cLjnz/show)
17 | * [Restrict Columns](https://jsfiddle.net/blakgeek/y2yfqydp/show)
18 | * [Post-process Data](https://jsfiddle.net/blakgeek/L4t7beeo/show)
19 |
20 | ## Code Sample
21 | HTML:
22 | ```html
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
41 |
42 | ```
43 | Javascript:
44 | ```js
45 | var app = angular.module('superDopeDemo', ['bg.spreadit']);
46 |
47 | app.controller('MyCtrl', ['$scope', function ($scope) {
48 |
49 | $scope.doStuffWithData = function(data, file, type) {
50 |
51 | console.log('file type: %s', type);
52 | console.log(data);
53 | };
54 |
55 | $scope.columns = [
56 | // matches becasue of title
57 | {
58 | title: 'Email',
59 | property: 'emailAddress'
60 | },
61 | // matches because of property
62 | {
63 | title: 'Last Name',
64 | property: 'last_name'
65 | },
66 | // matches because of alias
67 | {
68 | title: 'First Name',
69 | property: 'firstName',
70 | aliases: ['first_name', 'first']
71 | }
72 | ];
73 |
74 | $scope.postProcessors = [
75 |
76 | // concatenate first and last name to form a full name
77 | function (data) {
78 | if (data.firstName || data.last_name) {
79 | data.fullName = data.firstName + ' ' + data.last_name;
80 | }
81 | return data;
82 | },
83 | // capitalize full name
84 | function (data) {
85 | if (data.fullName) {
86 | data.fullName = data.fullName.toUpperCase();
87 | }
88 | return data;
89 | }
90 | ]
91 | }]);
92 | ```
93 |
--------------------------------------------------------------------------------
/bower.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "spreadit",
3 | "description": "Spreadsheet data importing simplified and 100% in the browser.",
4 | "main": [
5 | "dist/spreadit.js",
6 | "dist/spreadit.css"
7 | ],
8 | "authors": [
9 | "Carlos \"blakgeek\" Lawton"
10 | ],
11 | "license": "MIT",
12 | "keywords": [
13 | "spreadsheet",
14 | "angular",
15 | "angularjs",
16 | "javascript",
17 | "import",
18 | "xls",
19 | "xlsx",
20 | "csv",
21 | "tsv"
22 | ],
23 | "homepage": "https://github.com/blakgeek/spreadit",
24 | "ignore": [
25 | "**/.*",
26 | "node_modules",
27 | "bower_components",
28 | "test",
29 | "tests"
30 | ],
31 | "dependencies": {
32 | "angular": "<2",
33 | "js-xlsx": "^0.8.0",
34 | "papaparse": "^4.1.2",
35 | "lodash": "^4.11.2"
36 | }
37 | }
38 |
--------------------------------------------------------------------------------
/dev/spreadIt.css:
--------------------------------------------------------------------------------
1 | si-column-manager{position:fixed;top:0;left:0;bottom:0;right:0;visibility:hidden;background-color:rgba(255,255,255,0.95);z-index:2000}si-column-manager ul{list-style:none;margin:0;padding:0}si-column-manager.active{visibility:visible}si-column-manager header{position:absolute;top:0;right:0;left:0;margin:10px auto}si-column-manager footer{position:absolute;bottom:0;right:0;left:0;margin:10px auto}si-column-manager .si-toggle{display:-webkit-box;display:-moz-box;display:box;display:-webkit-flex;display:-moz-flex;display:-ms-flexbox;display:flex;-webkit-box-align:center;-moz-box-align:center;box-align:center;-webkit-align-items:center;-moz-align-items:center;-ms-align-items:center;-o-align-items:center;align-items:center;-ms-flex-align:center;white-space:nowrap}si-column-manager .si-toggle input[type="checkbox"]{-webkit-appearance:none;-moz-appearance:none;-ms-appearance:none;-o-appearance:none;appearance:none;display:none}si-column-manager .si-toggle input[type="checkbox"]:checked+i{background-color:#52a552}si-column-manager .si-toggle input[type="checkbox"]:checked+i:after{right:0;left:auto}si-column-manager .si-toggle i{-webkit-box-flex:0;-moz-box-flex:0;box-flex:0;-webkit-flex:0 0 40px;-moz-flex:0 0 40px;-ms-flex:0 0 40px;flex:0 0 40px;height:25px;position:relative;background-color:#f0f0f0;border-radius:25px;margin-right:8px}si-column-manager .si-toggle i:after{content:'';display:block;background-color:white;border-radius:20px;height:21px;width:21px;margin:2px;position:absolute;left:0;top:0}si-column-manager .si-column-manager-actions{display:-webkit-box;display:-moz-box;display:box;display:-webkit-flex;display:-moz-flex;display:-ms-flexbox;display:flex;-webkit-box-align:center;-moz-box-align:center;box-align:center;-webkit-align-items:center;-moz-align-items:center;-ms-align-items:center;-o-align-items:center;align-items:center;-ms-flex-align:center;width:calc(100% - 40px);max-width:800px}si-column-manager .si-column-manager-actions button{height:40px;padding:0 20px;font-size:inherit;font-family:inherit}si-column-manager .si-column-manager-actions .si-has-header{margin-right:auto}si-column-manager .si-column-manager-actions .si-close{line-height:40px;width:40px;text-align:center;border-radius:4px;font-size:24px;font-weight:bold;cursor:pointer}si-column-manager .si-column-manager-actions .si-close:hover{background-color:rgba(0,0,0,0.05)}si-column-manager .si-column-manager-actions .si-import{background-color:#52a552;color:white;text-shadow:0 1px 1px rgba(0,0,0,0.03);border:1px solid #56944a;border-radius:4px}si-column-manager footer.si-column-manager-actions{-webkit-box-pack:end;-moz-box-pack:end;box-pack:end;-webkit-justify-content:flex-end;-moz-justify-content:flex-end;-ms-justify-content:flex-end;-o-justify-content:flex-end;justify-content:flex-end;-ms-flex-pack:end}si-column-manager .si-column-manager-columns{left:0;right:0;top:0;bottom:0;position:absolute;margin:60px auto 60px;width:calc(100% - 40px);max-width:800px;counter-reset:column-counter;border-bottom:1px solid #ccc;border-top:1px solid #ccc;box-shadow:0 0 20px -4px rgba(0,0,0,0.2);overflow-y:auto;background-color:white}si-column-manager .si-column-manager-columns .si-column-manager-column{display:-webkit-box;display:-moz-box;display:box;display:-webkit-flex;display:-moz-flex;display:-ms-flexbox;display:flex;border:1px solid #ccc;border-bottom:none}si-column-manager .si-column-manager-columns .si-column-manager-column.si-column-ignored .si-column-manager-samples{text-decoration:line-through;color:#ccc}si-column-manager .si-column-manager-samples{counter-reset:sample-counter;-webkit-flex-grow:1;-moz-flex-grow:1;flex-grow:1;-ms-flex-positive:1;position:relative}si-column-manager .si-column-manager-samples .si-column-manager-sample-title{font-weight:bold;font-size:20px}si-column-manager .si-column-manager-samples .si-column-manager-sample-title:before{line-height:40px !important}si-column-manager .si-column-manager-samples li:last-of-type{border-bottom:none !important}si-column-manager .si-column-manager-samples .si-column-manager-sample-header{background-color:#e8e8e8;display:-webkit-box;display:-moz-box;display:box;display:-webkit-flex;display:-moz-flex;display:-ms-flexbox;display:flex;-webkit-box-align:center;-moz-box-align:center;box-align:center;-webkit-align-items:center;-moz-align-items:center;-ms-align-items:center;-o-align-items:center;align-items:center;-ms-flex-align:center;border-bottom:1px solid #ccc}si-column-manager .si-column-manager-samples .si-column-manager-sample-header:before{-webkit-box-flex:0;-moz-box-flex:0;box-flex:0;-webkit-flex:0 0 30px;-moz-flex:0 0 30px;-ms-flex:0 0 30px;flex:0 0 30px;background-color:#e8e8e8;display:block;line-height:30px;text-align:center;margin-right:10px;content:'\00a0';border-right:1px solid #ccc}si-column-manager .si-column-manager-samples .si-column-manager-sample-header:after{display:block;content:counter(column-counter,upper-alpha);counter-increment:column-counter;text-align:center;-webkit-flex-grow:1;-moz-flex-grow:1;flex-grow:1;-ms-flex-positive:1}si-column-manager .si-column-manager-samples .si-column-manager-sample{display:-webkit-box;display:-moz-box;display:box;display:-webkit-flex;display:-moz-flex;display:-ms-flexbox;display:flex;-webkit-box-align:center;-moz-box-align:center;box-align:center;-webkit-align-items:center;-moz-align-items:center;-ms-align-items:center;-o-align-items:center;align-items:center;-ms-flex-align:center;border-bottom:1px solid #ccc}si-column-manager .si-column-manager-samples .si-column-manager-sample:before{-webkit-box-flex:0;-moz-box-flex:0;box-flex:0;-webkit-flex:0 0 30px;-moz-flex:0 0 30px;-ms-flex:0 0 30px;flex:0 0 30px;background-color:#e8e8e8;display:block;line-height:30px;text-align:center;content:counter(sample-counter,decimal);counter-increment:sample-counter;margin-right:10px;border-right:1px solid #ccc;font-size:1rem;font-weight:normal}si-column-manager .si-column-manager-editor{-webkit-box-flex:0;-moz-box-flex:0;box-flex:0;-webkit-flex:0 0 300px;-moz-flex:0 0 300px;-ms-flex:0 0 300px;flex:0 0 300px;padding:20px;position:relative}si-column-manager .si-column-manager-editor input{width:100%;font-family:inherit;font-size:inherit;height:40px;padding:12px;box-sizing:border-box}si-column-manager .si-column-manager-editor .select-group{width:100%;box-sizing:border-box;margin-bottom:10px;position:relative;display:-webkit-box;display:-moz-box;display:box;display:-webkit-flex;display:-moz-flex;display:-ms-flexbox;display:flex;-webkit-box-align:center;-moz-box-align:center;box-align:center;-webkit-align-items:center;-moz-align-items:center;-ms-align-items:center;-o-align-items:center;align-items:center;-ms-flex-align:center;padding:0 10px;border:1px solid #ccc;background-color:white;color:black;border-radius:3px;height:40px}si-column-manager .si-column-manager-editor .select-group:after{font-family:Arrows;content:'\e901';margin-left:auto;display:inline-block;-webkit-box-flex:0;-moz-box-flex:0;box-flex:0;-webkit-flex:0 0 auto;-moz-flex:0 0 auto;-ms-flex:0 0 auto;flex:0 0 auto}si-column-manager .si-column-manager-editor .select-group select{-webkit-appearance:none;-moz-appearance:none;-ms-appearance:none;-o-appearance:none;appearance:none;position:absolute;top:0;left:0;width:100%;height:100%;opacity:0}si-column-manager .si-column-manager-editor label{margin-bottom:6px;font-size:20px;font-weight:bold;display:block}si-column-manager .si-column-manager-editor:after{background:linear-gradient(-45deg, #fff 9px, transparent 0),linear-gradient(-135deg, #fff 9px, transparent 0),linear-gradient(-45deg, #ccc 10px, transparent 0),linear-gradient(-135deg, #ccc 10px, transparent 0);background-position:left-bottom;background-repeat:repeat-y;background-size:20px 20px;content:" ";display:block;position:absolute;top:0;left:-20px;width:20px;height:100%;bottom:0}si-dropzone{display:-webkit-box;display:-moz-box;display:box;display:-webkit-flex;display:-moz-flex;display:-ms-flexbox;display:flex;-webkit-box-pack:center;-moz-box-pack:center;box-pack:center;-webkit-justify-content:center;-moz-justify-content:center;-ms-justify-content:center;-o-justify-content:center;justify-content:center;-ms-flex-pack:center;-webkit-box-align:center;-moz-box-align:center;box-align:center;-webkit-align-items:center;-moz-align-items:center;-ms-align-items:center;-o-align-items:center;align-items:center;-ms-flex-align:center;height:160px;border:1px #a0a0a0 dashed;border-radius:5px;width:calc(100% - 40px);max-width:800px;margin:20px auto 30px;box-sizing:border-box;position:relative;cursor:pointer;background-color:white;-webkit-transition:box-shadow 350ms;-moz-transition:box-shadow 350ms;transition:box-shadow 350ms}si-dropzone:hover{border-color:#303030;box-shadow:0 0 20px -4px rgba(0,0,0,0.4)}si-dropzone .si-icon{margin-left:20px;-webkit-box-flex:0;-moz-box-flex:0;box-flex:0;-webkit-flex:0 0 65px;-moz-flex:0 0 65px;-ms-flex:0 0 65px;flex:0 0 65px}si-dropzone .si-icon path{fill:#303030}si-dropzone .message{margin-right:20px;margin-left:10px;color:#303030;font-weight:normal;cursor:inherit}si-dropzone .message h2{font-size:20px;margin:0}si-dropzone .message p{margin:0}si-dropzone input[type="file"]{-webkit-appearance:none;-moz-appearance:none;-ms-appearance:none;-o-appearance:none;appearance:none;opacity:0;position:absolute;top:0;left:0;width:100% !important;height:100% !important;cursor:inherit}@font-face{font-family:'Arrows';src:url("../fonts/arrows/select-arrows.ttf?lym46w") format("truetype"),url("../fonts/arrows/select-arrows.woff?lym46w") format("woff"),url("../fonts/arrows/select-arrows.svg?lym46w#select-arrows") format("svg");font-weight:normal;font-style:normal}
2 |
--------------------------------------------------------------------------------
/dev/spreadit.js:
--------------------------------------------------------------------------------
1 | +function() {
2 |
3 | angular.module('bg.spreadit', []);
4 | }();
5 | +function () {
6 | 'use strict';
7 |
8 | angular.module('bg.spreadit').directive("siColumnManager", ['$timeout', '$parse', '$rootScope', directive]);
9 |
10 | function directive($timeout, $parse, $rootScope) {
11 | var supports = {
12 | xls: !!(window.XLSX && XLSX.utils),
13 | csv: !!(window.Papa && Papa.parse)
14 | };
15 |
16 | return {
17 | restrict: 'E',
18 | scope: {
19 | id: '@?siId',
20 | callback: '&?siChange',
21 | columns: '=?siColumns',
22 | sampleSize: '=?siSampleSize',
23 | excludeUnknownColumns: '=?siExcludeUnknownColumns',
24 | allowRenaming: '=?siAllowRenaming',
25 | // TODO: add support for these flags
26 | unknownColumnsGroupName: '=?siUnknownColumnsGroupName',
27 | groupUnknownColumns: '=?siGroupUnknownColumns',
28 | postProcessors: '=?siPostProcessors'
29 | },
30 | controller: ['$scope', '$element', '$attrs', controller],
31 | controllerAs: 'vm',
32 | templateUrl: '/columnManager.html'
33 | };
34 |
35 | function controller($scope, $element, $attrs) {
36 |
37 | _.defaults($scope, {
38 | id: "",
39 | columns: [],
40 | postProcessors: [],
41 | sampleSize: 3,
42 | excludeUnknownColumns: false,
43 | allowCustomRenaming: true,
44 | unknownColumnGroupName: '$extras',
45 | groupUnknownColumns: false,
46 | callback: angular.noop
47 | });
48 |
49 | var self = this;
50 | var columnMap = $scope.columns.reduce(function (map, entry) {
51 |
52 | var val;
53 | if (angular.isString(entry)) {
54 | val = {
55 | title: entry,
56 | property: entry
57 | };
58 | } else {
59 | val = entry;
60 | }
61 |
62 | map[String(val.property).trim().toLowerCase()] = val;
63 | map[String(val.title).trim().toLowerCase()] = val;
64 | if (angular.isArray(entry.aliases)) {
65 | entry.aliases.forEach(function (alias) {
66 | map[String(alias).trim().toLowerCase()] = val;
67 | });
68 | }
69 | return map;
70 | }, {});
71 | var titles = _.flatten($scope.columns.map(function (v) {
72 | if (angular.isString(v)) {
73 | return v;
74 | } else if (angular.isArray(v.aliases)) {
75 | return v.aliases.concat(v.title);
76 | } else {
77 | return v.title;
78 | }
79 | })).map(function (v) {
80 | return String(v).trim().toLowerCase();
81 | });
82 |
83 | var presult;
84 | var $file;
85 |
86 | $scope.$watch('hasHeader', function () {
87 |
88 | if ($file && self.active) {
89 | parseFile($file);
90 | }
91 | });
92 |
93 | this.remap = function (mapping) {
94 |
95 | remap(mapping);
96 | this.active = false;
97 | $element.removeClass('active');
98 | };
99 |
100 | this.cancel = function () {
101 | this.active = false;
102 | $element.removeClass('active');
103 | };
104 |
105 | function isHeader(values) {
106 |
107 | var isIt = $scope.hasHeader || values.some(function (value) {
108 | return titles.indexOf(String(value).trim().toLowerCase()) !== -1;
109 | });
110 | $scope.hasHeader = isIt;
111 | return isIt;
112 | }
113 |
114 | function isExcel(data) {
115 | return [0xD0, 0x09, 0x3C, 0x50].indexOf(data.charCodeAt(0)) !== -1;
116 | }
117 |
118 | function parseFile(file) {
119 |
120 | if (!file) {
121 | return;
122 | }
123 |
124 | var reader = new FileReader();
125 |
126 | if (reader.readAsBinaryString) {
127 |
128 | reader.onload = function (e) {
129 | preparse(file, e.target.result);
130 | };
131 |
132 | reader.readAsBinaryString(file);
133 | } else {
134 |
135 | reader.onload = function (e) {
136 |
137 | /* convert data to binary string */
138 | var data = new Uint8Array(e.target.result);
139 | var buffer = [];
140 | var i;
141 | for (i = 0; i < data.length; i++) {
142 | buffer[i] = String.fromCharCode(data[i]);
143 | }
144 | preparse(file, buffer.join(''));
145 | };
146 | reader.readAsArrayBuffer(file)
147 | }
148 | }
149 |
150 | function preparse(file, content) {
151 |
152 | if (supports.xls && isExcel(content)) {
153 | preparseExcel(content);
154 | } else if (supports.csv) {
155 | preparseCSV(file);
156 | }
157 | }
158 |
159 |
160 | function preparseExcel(content) {
161 |
162 | var c;
163 | var workbook = XLSX.read(content, {
164 | type: 'binary',
165 | sheetRows: $scope.sampleSize + 1,
166 | cellHTML: false,
167 | cellFormula: false
168 | });
169 | var sheet = workbook.Sheets[workbook.SheetNames[0]];
170 | var headerRange = XLSX.utils.decode_range(sheet['!ref']);
171 | var firstRow = [];
172 | var r = headerRange.s.r;
173 | for (c = headerRange.s.c; c < headerRange.e.c; c++) {
174 | var cell = sheet[XLSX.utils.encode_cell({r: r, c: c})];
175 | firstRow.push(cell ? String(cell.v).toLowerCase() : null);
176 | }
177 |
178 | var headers;
179 | var i = 1;
180 | if (!isHeader(firstRow)) {
181 | headers = [];
182 | for (c = headerRange.s.c; c <= headerRange.e.c; c++) {
183 | headers.push('Column ' + i++);
184 | }
185 | }
186 | var data = XLSX.utils.sheet_to_json(sheet, {
187 | header: headers,
188 | range: 0
189 | }).slice(0, 3);
190 |
191 | if ($scope.debug) {
192 | window.$spreadIt = {
193 | workbook: workbook,
194 | sheet: sheet,
195 | content: content
196 | }
197 | }
198 | preview({
199 | type: 'excel',
200 | raw: content,
201 | data: data,
202 | headers: headers || Object.keys(data[0])
203 | });
204 | }
205 |
206 | function preparseCsvWithHeader(file) {
207 |
208 | Papa.parse(file, {
209 | header: true,
210 | preview: $scope.sampleSize,
211 | complete: function (result) {
212 |
213 | var headers = Object.keys(result.data[0]);
214 | preview({
215 | type: 'csv',
216 | data: result.data,
217 | raw: file,
218 | headers: headers
219 | });
220 | }
221 | });
222 | }
223 |
224 | function preparseCsvSansHeader(file) {
225 |
226 | Papa.parse(file, {
227 | header: false,
228 | preview: $scope.sampleSize,
229 | complete: function (result) {
230 |
231 | var headers = result.data[0].map(function (column, i) {
232 | return 'Column ' + (i + 1);
233 | });
234 |
235 | var data = result.data.map(function (columns) {
236 |
237 | var obj = {};
238 | columns.forEach(function (column, i) {
239 | obj['Column ' + (i + 1)] = column;
240 | });
241 | return obj;
242 | });
243 | preview({
244 | type: 'csv',
245 | headers: headers,
246 | data: data,
247 | raw: file
248 | });
249 | }
250 | });
251 | }
252 |
253 | function preparseCSV(file) {
254 | Papa.parse(file, {
255 | preview: 1,
256 | complete: function (result) {
257 | var firstRow = result.data[0];
258 | if (firstRow && isHeader(firstRow)) {
259 | preparseCsvWithHeader(file);
260 | } else {
261 | preparseCsvSansHeader(file);
262 | }
263 | }
264 | });
265 | }
266 |
267 | function parseExcel(content, headers) {
268 | var c;
269 | var workbook = XLSX.read(content, {
270 | type: 'binary',
271 | cellHTML: false,
272 | cellFormula: false
273 | });
274 | var sheet = workbook.Sheets[workbook.SheetNames[0]];
275 | var headerRange = XLSX.utils.decode_range(sheet['!ref']);
276 | var firstRow = [];
277 | var r = headerRange.s.r;
278 | for (c = headerRange.s.c; c < headerRange.e.c; c++) {
279 | var cell = sheet[XLSX.utils.encode_cell({r: r, c: c})];
280 | firstRow.push(cell ? String(cell.v).toLowerCase() : null);
281 | }
282 |
283 | var data = XLSX.utils.sheet_to_json(sheet, {
284 | header: headers,
285 | range: isHeader(firstRow) ? 1 : 0
286 | }).map(function (result) {
287 |
288 | delete result.$skip$;
289 | return result;
290 | });
291 |
292 |
293 | $scope.callback({
294 | $type: 'excel',
295 | $file: $file,
296 | $data: postProcess(data)
297 | });
298 | }
299 |
300 | function parseCsv(file, headers) {
301 |
302 | Papa.parse(file, {
303 | header: false,
304 | complete: function (result) {
305 |
306 | var firstRow = result.data[0];
307 | if (isHeader(firstRow)) {
308 | result.data.splice(0, 1);
309 | }
310 | var data = result.data.map(function (columns) {
311 |
312 | var obj = {};
313 | columns.forEach(function (column, i) {
314 |
315 | if (headers[i] !== '$skip$') {
316 | obj[headers[i]] = column;
317 | }
318 | });
319 | return obj;
320 | });
321 | $scope.callback({
322 | $type: 'csv',
323 | $file: $file,
324 | $data: postProcess(data)
325 | });
326 | }
327 | });
328 | }
329 |
330 | function preview(result) {
331 |
332 | $timeout(function () {
333 |
334 | var preview = self.preview = [];
335 |
336 | result.headers.forEach(function (header) {
337 |
338 | var normalizedHeader = header.toLowerCase().trim();
339 | var mapping;
340 | if (columnMap[normalizedHeader]) {
341 | mapping = columnMap[normalizedHeader];
342 | } else if ($scope.excludeUnknownColumns) {
343 | mapping = {
344 | title: 'Ignore This Column',
345 | property: '$skip$'
346 | }
347 | } else {
348 | mapping = {
349 | title: 'Keep This Column',
350 | property: false
351 | };
352 | }
353 | preview.push({
354 | header: header,
355 | mapping: mapping,
356 | custom: header,
357 | sample: result.data.map(function (v) {
358 | return v[header];
359 | })
360 | });
361 | });
362 | var titles = [];
363 | if (!$scope.excludeUnknownColumns) {
364 | titles.push({
365 | title: 'Keep This Column',
366 | property: false
367 | });
368 | }
369 |
370 | titles.push({
371 | title: 'Ignore This Column',
372 | property: '$skip$'
373 | });
374 |
375 | if (!$scope.excludeUnknownColumns && $scope.allowCustomRenaming) {
376 | titles.push({
377 | title: 'Rename This Column',
378 | property: '$rename$'
379 | });
380 | }
381 |
382 | self.titles = titles.concat($scope.columns.map(function (column) {
383 |
384 | if (angular.isObject(column)) {
385 | return column;
386 | }
387 |
388 | return {
389 | title: column,
390 | property: column
391 | }
392 | }));
393 | presult = result;
394 | });
395 | }
396 |
397 | function remap(mapping) {
398 |
399 | var headers = mapping.map(function (column) {
400 |
401 | var mapping = column.mapping;
402 | if (mapping.property === false) {
403 | return column.header;
404 | } else if (mapping.property === '$rename$') {
405 | return column.custom;
406 | } else {
407 | return column.mapping.property;
408 | }
409 | });
410 | if (presult.type === 'csv') {
411 | parseCsv(presult.raw, headers);
412 | } else {
413 | parseExcel(presult.raw, headers);
414 | }
415 | }
416 |
417 | $rootScope.$on('si.preview', function (e, id, file) {
418 |
419 | if (file && id === $scope.id) {
420 | $file = file;
421 | $scope.hasHeader = false;
422 | parseFile(file);
423 | self.active = true;
424 | $element.addClass('active');
425 | }
426 | });
427 |
428 | function postProcess(data) {
429 |
430 | if(!$scope.postProcessors.length) {
431 | return data;
432 | }
433 |
434 | return data.map(function(obj) {
435 |
436 | $scope.postProcessors.forEach(function(fn) {
437 | fn(obj);
438 | });
439 | return obj;
440 | })
441 | }
442 | }
443 | }
444 |
445 | }();
446 |
447 | +function () {
448 | 'use strict';
449 |
450 | angular.module('bg.spreadit').directive("siDropzone", ['$rootScope', directive]);
451 | angular.module('bg.spreadit').directive("siImporter", ['$rootScope', directive]);
452 |
453 | function directive($rootScope) {
454 | var accepts = [];
455 |
456 | if(!!(window.XLSX && XLSX.utils)) {
457 | accepts.push('.xls', '.xlsx');
458 | }
459 |
460 | if(!!(window.Papa && Papa.parse)) {
461 | accepts.push('.csv', '.tsv', '.txt');
462 | }
463 |
464 | return {
465 | restrict: 'E',
466 | scope: {
467 | id: '@siId'
468 | },
469 | controller: controller,
470 | controllerAs: 'vm',
471 | templateUrl: '/dropzone.html',
472 | link: link
473 | };
474 |
475 | function controller() {
476 |
477 | }
478 |
479 | function link($scope, $element, $attrs) {
480 |
481 | _.defaults($scope, {
482 | id: ""
483 | });
484 |
485 | var element = $element[0];
486 | element.setAttribute('accepts', accepts.join());
487 | element.querySelector('input[type="file"]').addEventListener('change', function (e) {
488 | $rootScope.$emit('si.preview', $scope.id, e.target.files[0]);
489 | });
490 | }
491 | }
492 |
493 | }();
494 |
495 | +function () {
496 | 'use strict';
497 |
498 | angular.module('bg.spreadit').directive("siFileSelect", ['$rootScope', directive]);
499 | angular.module('bg.spreadit').directive("siTrigger", ['$rootScope', directive]);
500 |
501 | function directive($rootScope) {
502 | var accepts = [];
503 |
504 | if(!!(window.XLSX && XLSX.utils)) {
505 | accepts.push('.xls', '.xlsx');
506 | }
507 |
508 | if(!!(window.Papa && Papa.parse)) {
509 | accepts.push('.csv', '.tsv', '.txt');
510 | }
511 |
512 | return {
513 | restrict: 'EA',
514 | scope: {
515 | id: '@?siFileSelect'
516 | },
517 | link: link
518 | };
519 |
520 | function link($scope, $element, $attrs) {
521 |
522 | var element = $element[0];
523 | var fileEl = $element;
524 | var tagName = element.tagName.toLowerCase();
525 | var isFileInput = tagName === 'input' && $attrs.type && $attrs.type.toLowerCase() === 'file';
526 | var isLink = tagName === 'a';
527 |
528 | if(angular.isDefined($attrs.siFileSelect)) {
529 | $scope.id = $attrs.siFileSelect;
530 | }
531 |
532 | if (!isFileInput) {
533 | fileEl = angular.element('');
534 | var label = angular.element('');
535 | label.css('visibility', 'hidden').css('position', 'absolute').css('overflow', 'hidden')
536 | .css('width', '0px').css('height', '0px').css('border', 'none')
537 | .css('margin', '0px').css('padding', '0px').attr('tabindex', '-1');
538 | document.body.appendChild(label.append(fileEl)[0]);
539 | $element.on('click', function(e) {
540 | e.preventDefault();
541 | fileEl[0].click();
542 | });
543 | }
544 |
545 | if(isLink) {
546 | $element.attr('href', 'javascript:');
547 | }
548 |
549 | fileEl.attr('accepts', accepts.join());
550 | fileEl.on('change', onChange);
551 |
552 | function onChange(e) {
553 | $rootScope.$emit('si.preview', $scope.id, e.target.files[0]);
554 | }
555 | }
556 | }
557 |
558 | }();
559 |
560 | +function () {
561 | 'use strict';
562 |
563 | angular.module('bg.spreadit').service("Spreadit", ['$rootScope', service]);
564 |
565 | function service($rootScope) {
566 |
567 | }
568 |
569 | }();
570 |
571 | angular.module('bg.spreadit').run(['$templateCache', function($templateCache) {
572 | 'use strict';
573 |
574 | $templateCache.put('/columnManager.html',
575 | "
- {{column.header}}
- {{sample}}
"
576 | );
577 |
578 |
579 | $templateCache.put('/dropzone.html',
580 | "Wanna Import a spreadsheet (Excel or CSV)?
Click here or drag and drop your file like it's hot.
"
586 | );
587 |
588 | }]);
589 |
--------------------------------------------------------------------------------
/dist/spreadIt.css:
--------------------------------------------------------------------------------
1 | si-column-manager{position:fixed;top:0;left:0;bottom:0;right:0;visibility:hidden;background-color:rgba(255,255,255,0.95);z-index:2000}si-column-manager ul{list-style:none;margin:0;padding:0}si-column-manager.active{visibility:visible}si-column-manager header{position:absolute;top:0;right:0;left:0;margin:10px auto}si-column-manager footer{position:absolute;bottom:0;right:0;left:0;margin:10px auto}si-column-manager .si-toggle{display:-webkit-box;display:-moz-box;display:box;display:-webkit-flex;display:-moz-flex;display:-ms-flexbox;display:flex;-webkit-box-align:center;-moz-box-align:center;box-align:center;-webkit-align-items:center;-moz-align-items:center;-ms-align-items:center;-o-align-items:center;align-items:center;-ms-flex-align:center;white-space:nowrap}si-column-manager .si-toggle input[type="checkbox"]{-webkit-appearance:none;-moz-appearance:none;-ms-appearance:none;-o-appearance:none;appearance:none;display:none}si-column-manager .si-toggle input[type="checkbox"]:checked+i{background-color:#52a552}si-column-manager .si-toggle input[type="checkbox"]:checked+i:after{right:0;left:auto}si-column-manager .si-toggle i{-webkit-box-flex:0;-moz-box-flex:0;box-flex:0;-webkit-flex:0 0 40px;-moz-flex:0 0 40px;-ms-flex:0 0 40px;flex:0 0 40px;height:25px;position:relative;background-color:#f0f0f0;border-radius:25px;margin-right:8px}si-column-manager .si-toggle i:after{content:'';display:block;background-color:white;border-radius:20px;height:21px;width:21px;margin:2px;position:absolute;left:0;top:0}si-column-manager .si-column-manager-actions{display:-webkit-box;display:-moz-box;display:box;display:-webkit-flex;display:-moz-flex;display:-ms-flexbox;display:flex;-webkit-box-align:center;-moz-box-align:center;box-align:center;-webkit-align-items:center;-moz-align-items:center;-ms-align-items:center;-o-align-items:center;align-items:center;-ms-flex-align:center;width:calc(100% - 40px);max-width:800px}si-column-manager .si-column-manager-actions button{height:40px;padding:0 20px;font-size:inherit;font-family:inherit}si-column-manager .si-column-manager-actions .si-has-header{margin-right:auto}si-column-manager .si-column-manager-actions .si-close{line-height:40px;width:40px;text-align:center;border-radius:4px;font-size:24px;font-weight:bold;cursor:pointer}si-column-manager .si-column-manager-actions .si-close:hover{background-color:rgba(0,0,0,0.05)}si-column-manager .si-column-manager-actions .si-import{background-color:#52a552;color:white;text-shadow:0 1px 1px rgba(0,0,0,0.03);border:1px solid #56944a;border-radius:4px}si-column-manager footer.si-column-manager-actions{-webkit-box-pack:end;-moz-box-pack:end;box-pack:end;-webkit-justify-content:flex-end;-moz-justify-content:flex-end;-ms-justify-content:flex-end;-o-justify-content:flex-end;justify-content:flex-end;-ms-flex-pack:end}si-column-manager .si-column-manager-columns{left:0;right:0;top:0;bottom:0;position:absolute;margin:60px auto 60px;width:calc(100% - 40px);max-width:800px;counter-reset:column-counter;border-bottom:1px solid #ccc;border-top:1px solid #ccc;box-shadow:0 0 20px -4px rgba(0,0,0,0.2);overflow-y:auto;background-color:white}si-column-manager .si-column-manager-columns .si-column-manager-column{display:-webkit-box;display:-moz-box;display:box;display:-webkit-flex;display:-moz-flex;display:-ms-flexbox;display:flex;border:1px solid #ccc;border-bottom:none}si-column-manager .si-column-manager-columns .si-column-manager-column.si-column-ignored .si-column-manager-samples{text-decoration:line-through;color:#ccc}si-column-manager .si-column-manager-samples{counter-reset:sample-counter;-webkit-flex-grow:1;-moz-flex-grow:1;flex-grow:1;-ms-flex-positive:1;position:relative}si-column-manager .si-column-manager-samples .si-column-manager-sample-title{font-weight:bold;font-size:20px}si-column-manager .si-column-manager-samples .si-column-manager-sample-title:before{line-height:40px !important}si-column-manager .si-column-manager-samples li:last-of-type{border-bottom:none !important}si-column-manager .si-column-manager-samples .si-column-manager-sample-header{background-color:#e8e8e8;display:-webkit-box;display:-moz-box;display:box;display:-webkit-flex;display:-moz-flex;display:-ms-flexbox;display:flex;-webkit-box-align:center;-moz-box-align:center;box-align:center;-webkit-align-items:center;-moz-align-items:center;-ms-align-items:center;-o-align-items:center;align-items:center;-ms-flex-align:center;border-bottom:1px solid #ccc}si-column-manager .si-column-manager-samples .si-column-manager-sample-header:before{-webkit-box-flex:0;-moz-box-flex:0;box-flex:0;-webkit-flex:0 0 30px;-moz-flex:0 0 30px;-ms-flex:0 0 30px;flex:0 0 30px;background-color:#e8e8e8;display:block;line-height:30px;text-align:center;margin-right:10px;content:'\00a0';border-right:1px solid #ccc}si-column-manager .si-column-manager-samples .si-column-manager-sample-header:after{display:block;content:counter(column-counter,upper-alpha);counter-increment:column-counter;text-align:center;-webkit-flex-grow:1;-moz-flex-grow:1;flex-grow:1;-ms-flex-positive:1}si-column-manager .si-column-manager-samples .si-column-manager-sample{display:-webkit-box;display:-moz-box;display:box;display:-webkit-flex;display:-moz-flex;display:-ms-flexbox;display:flex;-webkit-box-align:center;-moz-box-align:center;box-align:center;-webkit-align-items:center;-moz-align-items:center;-ms-align-items:center;-o-align-items:center;align-items:center;-ms-flex-align:center;border-bottom:1px solid #ccc}si-column-manager .si-column-manager-samples .si-column-manager-sample:before{-webkit-box-flex:0;-moz-box-flex:0;box-flex:0;-webkit-flex:0 0 30px;-moz-flex:0 0 30px;-ms-flex:0 0 30px;flex:0 0 30px;background-color:#e8e8e8;display:block;line-height:30px;text-align:center;content:counter(sample-counter,decimal);counter-increment:sample-counter;margin-right:10px;border-right:1px solid #ccc;font-size:1rem;font-weight:normal}si-column-manager .si-column-manager-editor{-webkit-box-flex:0;-moz-box-flex:0;box-flex:0;-webkit-flex:0 0 300px;-moz-flex:0 0 300px;-ms-flex:0 0 300px;flex:0 0 300px;padding:20px;position:relative}si-column-manager .si-column-manager-editor input{width:100%;font-family:inherit;font-size:inherit;height:40px;padding:12px;box-sizing:border-box}si-column-manager .si-column-manager-editor .select-group{width:100%;box-sizing:border-box;margin-bottom:10px;position:relative;display:-webkit-box;display:-moz-box;display:box;display:-webkit-flex;display:-moz-flex;display:-ms-flexbox;display:flex;-webkit-box-align:center;-moz-box-align:center;box-align:center;-webkit-align-items:center;-moz-align-items:center;-ms-align-items:center;-o-align-items:center;align-items:center;-ms-flex-align:center;padding:0 10px;border:1px solid #ccc;background-color:white;color:black;border-radius:3px;height:40px}si-column-manager .si-column-manager-editor .select-group:after{font-family:Arrows;content:'\e901';margin-left:auto;display:inline-block;-webkit-box-flex:0;-moz-box-flex:0;box-flex:0;-webkit-flex:0 0 auto;-moz-flex:0 0 auto;-ms-flex:0 0 auto;flex:0 0 auto}si-column-manager .si-column-manager-editor .select-group select{-webkit-appearance:none;-moz-appearance:none;-ms-appearance:none;-o-appearance:none;appearance:none;position:absolute;top:0;left:0;width:100%;height:100%;opacity:0}si-column-manager .si-column-manager-editor label{margin-bottom:6px;font-size:20px;font-weight:bold;display:block}si-column-manager .si-column-manager-editor:after{background:linear-gradient(-45deg, #fff 9px, transparent 0),linear-gradient(-135deg, #fff 9px, transparent 0),linear-gradient(-45deg, #ccc 10px, transparent 0),linear-gradient(-135deg, #ccc 10px, transparent 0);background-position:left-bottom;background-repeat:repeat-y;background-size:20px 20px;content:" ";display:block;position:absolute;top:0;left:-20px;width:20px;height:100%;bottom:0}si-dropzone{display:-webkit-box;display:-moz-box;display:box;display:-webkit-flex;display:-moz-flex;display:-ms-flexbox;display:flex;-webkit-box-pack:center;-moz-box-pack:center;box-pack:center;-webkit-justify-content:center;-moz-justify-content:center;-ms-justify-content:center;-o-justify-content:center;justify-content:center;-ms-flex-pack:center;-webkit-box-align:center;-moz-box-align:center;box-align:center;-webkit-align-items:center;-moz-align-items:center;-ms-align-items:center;-o-align-items:center;align-items:center;-ms-flex-align:center;height:160px;border:1px #a0a0a0 dashed;border-radius:5px;width:calc(100% - 40px);max-width:800px;margin:20px auto 30px;box-sizing:border-box;position:relative;cursor:pointer;background-color:white;-webkit-transition:box-shadow 350ms;-moz-transition:box-shadow 350ms;transition:box-shadow 350ms}si-dropzone:hover{border-color:#303030;box-shadow:0 0 20px -4px rgba(0,0,0,0.4)}si-dropzone .si-icon{margin-left:20px;-webkit-box-flex:0;-moz-box-flex:0;box-flex:0;-webkit-flex:0 0 65px;-moz-flex:0 0 65px;-ms-flex:0 0 65px;flex:0 0 65px}si-dropzone .si-icon path{fill:#303030}si-dropzone .message{margin-right:20px;margin-left:10px;color:#303030;font-weight:normal;cursor:inherit}si-dropzone .message h2{font-size:20px;margin:0}si-dropzone .message p{margin:0}si-dropzone input[type="file"]{-webkit-appearance:none;-moz-appearance:none;-ms-appearance:none;-o-appearance:none;appearance:none;opacity:0;position:absolute;top:0;left:0;width:100% !important;height:100% !important;cursor:inherit}@font-face{font-family:'Arrows';src:url("../fonts/arrows/select-arrows.ttf?lym46w") format("truetype"),url("../fonts/arrows/select-arrows.woff?lym46w") format("woff"),url("../fonts/arrows/select-arrows.svg?lym46w#select-arrows") format("svg");font-weight:normal;font-style:normal}
2 |
--------------------------------------------------------------------------------
/dist/spreadit.min.js:
--------------------------------------------------------------------------------
1 | +function(){angular.module("bg.spreadit",[])}(),+function(){"use strict";function a(a,b,c){function d(b,d,f){function g(a){var c=b.hasHeader||a.some(function(a){return-1!==x.indexOf(String(a).trim().toLowerCase())});return b.hasHeader=c,c}function h(a){return-1!==[208,9,60,80].indexOf(a.charCodeAt(0))}function i(a){if(a){var b=new FileReader;b.readAsBinaryString?(b.onload=function(b){j(a,b.target.result)},b.readAsBinaryString(a)):(b.onload=function(b){var c,d=new Uint8Array(b.target.result),e=[];for(c=0;c');var l=angular.element("");l.css("visibility","hidden").css("position","absolute").css("overflow","hidden").css("width","0px").css("height","0px").css("border","none").css("margin","0px").css("padding","0px").attr("tabindex","-1"),document.body.appendChild(l.append(h)[0]),d.on("click",function(a){a.preventDefault(),h[0].click()})}k&&d.attr("href","javascript:"),h.attr("accepts",c.join()),h.on("change",f)}var c=[];return window.XLSX&&XLSX.utils&&c.push(".xls",".xlsx"),window.Papa&&Papa.parse&&c.push(".csv",".tsv",".txt"),{restrict:"EA",scope:{id:"@?siFileSelect"},link:b}}angular.module("bg.spreadit").directive("siFileSelect",["$rootScope",a]),angular.module("bg.spreadit").directive("siTrigger",["$rootScope",a])}(),+function(){"use strict";function a(a){}angular.module("bg.spreadit").service("Spreadit",["$rootScope",a])}(),angular.module("bg.spreadit").run(["$templateCache",function(a){"use strict";a.put("/columnManager.html",'- {{column.header}}
- {{sample}}
'),a.put("/dropzone.html",'Wanna Import a spreadsheet (Excel or CSV)?
Click here or drag and drop your file like it\'s hot.
')}]);
--------------------------------------------------------------------------------
/example/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | Spreadit Demo
6 |
7 |
8 |
54 |
55 |
56 |
57 |
58 |
59 |
60 |
61 |
62 |
63 |
64 |
65 |
68 |
69 |
70 |
73 |
74 |
78 |
79 |
83 |
84 |
85 |
86 |
87 |
88 |
89 |
134 |
135 |
--------------------------------------------------------------------------------
/example/sample.csv:
--------------------------------------------------------------------------------
1 | id,first_name,last_name,email,gender,ip_address
2 | 1,Robin,Parker,rparker0@adobe.com,Female,57.233.108.210
3 | 2,Joyce,Reynolds,jreynolds1@hugedomains.com,Female,129.125.90.145
4 | 3,Pamela,Freeman,pfreeman2@163.com,Female,58.29.172.21
5 | 4,Angela,Nichols,anichols3@huffingtonpost.com,Female,94.19.251.40
6 | 5,Lawrence,Spencer,lspencer4@bizjournals.com,Male,50.107.175.59
7 | 6,Julia,Montgomery,jmontgomery5@globo.com,Female,79.244.198.237
8 | 7,Gloria,Greene,ggreene6@parallels.com,Female,209.45.239.143
9 | 8,Daniel,Miller,dmiller7@dion.ne.jp,Male,7.236.23.77
10 | 9,Terry,Nguyen,tnguyen8@de.vu,Male,60.16.127.120
11 | 10,Rose,Jones,rjones9@geocities.jp,Female,149.90.190.214
12 | 11,Albert,Gray,agraya@gizmodo.com,Male,172.158.251.68
13 | 12,Douglas,Burns,dburnsb@netlog.com,Male,18.243.232.149
14 | 13,Ruby,Hansen,rhansenc@tinypic.com,Female,55.158.112.244
15 | 14,Elizabeth,Thomas,ethomasd@google.es,Female,212.201.231.20
16 | 15,Ashley,Carpenter,acarpentere@cornell.edu,Female,136.249.115.187
17 | 16,Sharon,Fox,sfoxf@feedburner.com,Female,15.102.110.182
18 | 17,Kimberly,Jackson,kjacksong@businesswire.com,Female,76.35.79.37
19 | 18,Mary,Little,mlittleh@mtv.com,Female,217.46.149.59
20 | 19,Henry,Garcia,hgarciai@e-recht24.de,Male,88.59.59.30
21 | 20,Joshua,Owens,jowensj@is.gd,Male,91.227.198.91
22 | 21,Evelyn,Wright,ewrightk@ustream.tv,Female,241.101.137.232
23 | 22,Barbara,Smith,bsmithl@guardian.co.uk,Female,42.26.163.120
24 | 23,Henry,Gonzales,hgonzalesm@mac.com,Male,37.35.170.253
25 | 24,Larry,Vasquez,lvasquezn@gnu.org,Male,80.30.235.250
26 | 25,Janet,Welch,jwelcho@hud.gov,Female,182.66.31.193
27 | 26,Frances,Fowler,ffowlerp@redcross.org,Female,154.92.7.21
28 | 27,Angela,Cox,acoxq@si.edu,Female,167.223.205.252
29 | 28,Henry,Andrews,handrewsr@sun.com,Male,34.105.213.72
30 | 29,Walter,Frazier,wfraziers@123-reg.co.uk,Male,121.207.248.168
31 | 30,Joyce,Kelly,jkellyt@scientificamerican.com,Female,57.168.0.55
32 | 31,Terry,Stephens,tstephensu@clickbank.net,Male,204.56.114.219
33 | 32,Russell,Edwards,redwardsv@cbsnews.com,Male,45.134.23.179
34 | 33,Helen,Boyd,hboydw@ameblo.jp,Female,31.248.43.237
35 | 34,Susan,Ferguson,sfergusonx@uiuc.edu,Female,34.177.104.172
36 | 35,Kenneth,Ortiz,kortizy@google.co.jp,Male,209.233.114.78
37 | 36,Bonnie,Day,bdayz@archive.org,Female,97.151.182.199
38 | 37,Russell,Allen,rallen10@rambler.ru,Male,88.159.60.139
39 | 38,Lillian,Cruz,lcruz11@house.gov,Female,216.221.154.192
40 | 39,Wayne,Ferguson,wferguson12@hostgator.com,Male,2.228.83.166
41 | 40,Catherine,Tucker,ctucker13@last.fm,Female,136.16.207.52
42 | 41,Johnny,Collins,jcollins14@wordpress.com,Male,59.240.137.66
43 | 42,Elizabeth,Weaver,eweaver15@usatoday.com,Female,243.43.50.232
44 | 43,Victor,Diaz,vdiaz16@comsenz.com,Male,250.207.218.12
45 | 44,Patrick,Taylor,ptaylor17@aboutads.info,Male,31.78.183.53
46 | 45,Ruth,Garza,rgarza18@cloudflare.com,Female,193.35.7.241
47 | 46,Eric,Green,egreen19@un.org,Male,208.115.114.15
48 | 47,Sharon,Fields,sfields1a@walmart.com,Female,201.84.150.113
49 | 48,Lisa,Montgomery,lmontgomery1b@ifeng.com,Female,236.120.118.122
50 | 49,Kathy,Reynolds,kreynolds1c@apache.org,Female,54.244.56.244
51 | 50,Louise,Stewart,lstewart1d@liveinternet.ru,Female,111.123.66.30
52 | 51,Jonathan,Rivera,jrivera1e@cocolog-nifty.com,Male,54.245.153.221
53 | 52,Paul,Price,pprice1f@storify.com,Male,186.10.142.95
54 | 53,Amanda,Bishop,abishop1g@disqus.com,Female,153.191.108.49
55 | 54,Ruth,Mills,rmills1h@macromedia.com,Female,0.23.187.193
56 | 55,Donald,Patterson,dpatterson1i@dot.gov,Male,173.146.245.86
57 | 56,Shawn,Taylor,staylor1j@nhs.uk,Male,68.60.201.240
58 | 57,Heather,Stevens,hstevens1k@disqus.com,Female,138.20.167.31
59 | 58,Carolyn,Alexander,calexander1l@bing.com,Female,155.15.224.206
60 | 59,Sean,Welch,swelch1m@exblog.jp,Male,217.194.90.192
61 | 60,Carl,Bishop,cbishop1n@census.gov,Male,18.167.146.150
62 | 61,Sandra,Johnston,sjohnston1o@europa.eu,Female,57.159.14.77
63 | 62,Rebecca,Daniels,rdaniels1p@google.ru,Female,107.115.158.160
64 | 63,Howard,Morris,hmorris1q@tamu.edu,Male,226.74.252.243
65 | 64,Rachel,Welch,rwelch1r@imgur.com,Female,139.125.3.150
66 | 65,Russell,Torres,rtorres1s@hibu.com,Male,25.233.48.44
67 | 66,Andrew,James,ajames1t@surveymonkey.com,Male,209.213.136.2
68 | 67,Helen,Jordan,hjordan1u@mysql.com,Female,155.90.57.202
69 | 68,Paula,Willis,pwillis1v@xinhuanet.com,Female,182.235.216.133
70 | 69,Jason,Gardner,jgardner1w@nifty.com,Male,159.254.244.49
71 | 70,Douglas,Graham,dgraham1x@seesaa.net,Male,180.75.190.237
72 | 71,Stephanie,Rivera,srivera1y@sourceforge.net,Female,232.57.216.204
73 | 72,Wayne,Morales,wmorales1z@alexa.com,Male,69.75.5.47
74 | 73,Christopher,Kelly,ckelly20@arizona.edu,Male,187.107.178.37
75 | 74,Nancy,Gordon,ngordon21@multiply.com,Female,163.149.194.248
76 | 75,Judy,Franklin,jfranklin22@google.de,Female,253.113.100.51
77 | 76,Laura,Nelson,lnelson23@statcounter.com,Female,32.200.227.150
78 | 77,Judy,Banks,jbanks24@reference.com,Female,160.94.78.104
79 | 78,Jimmy,Arnold,jarnold25@linkedin.com,Male,189.153.8.124
80 | 79,Janet,Myers,jmyers26@jimdo.com,Female,53.81.202.3
81 | 80,Rebecca,Bishop,rbishop27@statcounter.com,Female,235.207.8.133
82 | 81,Fred,Black,fblack28@newyorker.com,Male,36.175.7.244
83 | 82,Harry,Harrison,hharrison29@ehow.com,Male,161.107.17.226
84 | 83,Diana,Flores,dflores2a@spiegel.de,Female,52.134.213.82
85 | 84,Katherine,Edwards,kedwards2b@bloglines.com,Female,78.73.183.8
86 | 85,Diane,Howell,dhowell2c@salon.com,Female,158.172.24.102
87 | 86,Harold,Welch,hwelch2d@ning.com,Male,135.17.58.249
88 | 87,Jean,Franklin,jfranklin2e@free.fr,Female,169.163.147.254
89 | 88,Tammy,Hall,thall2f@unesco.org,Female,126.40.80.22
90 | 89,Julie,Matthews,jmatthews2g@seesaa.net,Female,94.53.71.164
91 | 90,Ann,Boyd,aboyd2h@washington.edu,Female,214.103.149.43
92 | 91,Evelyn,Fox,efox2i@taobao.com,Female,14.12.173.215
93 | 92,Amy,Moore,amoore2j@ask.com,Female,56.196.98.125
94 | 93,Anne,Gray,agray2k@printfriendly.com,Female,231.245.141.184
95 | 94,Diane,Martin,dmartin2l@bizjournals.com,Female,127.225.182.49
96 | 95,Rose,Alvarez,ralvarez2m@wired.com,Female,240.8.61.170
97 | 96,Martha,Ellis,mellis2n@usnews.com,Female,18.230.235.105
98 | 97,Sandra,Ryan,sryan2o@a8.net,Female,65.161.158.156
99 | 98,Irene,Gray,igray2p@berkeley.edu,Female,126.224.255.223
100 | 99,Stephen,Garrett,sgarrett2q@rakuten.co.jp,Male,79.232.241.175
101 | 100,Carolyn,Garza,cgarza2r@cnet.com,Female,242.154.162.54
102 |
--------------------------------------------------------------------------------
/example/sample.xlsx:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/blakgeek/spreadit/9d600a5f20031b719838cef4b33bcf9a57c015c5/example/sample.xlsx
--------------------------------------------------------------------------------
/fonts/arrows/select-arrows.svg:
--------------------------------------------------------------------------------
1 |
2 |
3 |
--------------------------------------------------------------------------------
/fonts/arrows/select-arrows.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/blakgeek/spreadit/9d600a5f20031b719838cef4b33bcf9a57c015c5/fonts/arrows/select-arrows.ttf
--------------------------------------------------------------------------------
/fonts/arrows/select-arrows.woff:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/blakgeek/spreadit/9d600a5f20031b719838cef4b33bcf9a57c015c5/fonts/arrows/select-arrows.woff
--------------------------------------------------------------------------------
/importer-screenshot.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/blakgeek/spreadit/9d600a5f20031b719838cef4b33bcf9a57c015c5/importer-screenshot.png
--------------------------------------------------------------------------------
/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "spreadit",
3 | "version": "1.0.5",
4 | "description": "Spreadsheet data importing simplified and 100% in the browser",
5 | "main": "Gruntfile.js",
6 | "scripts": {
7 | "test": "echo \"Error: no test specified\" && exit 1"
8 | },
9 | "repository": {
10 | "type": "git",
11 | "url": "git+https://github.com/blakgeek/spreadit.git"
12 | },
13 | "keywords": [
14 | "spreadsheet",
15 | "angular",
16 | "angularjs",
17 | "javascript",
18 | "import",
19 | "xls",
20 | "xlsx",
21 | "csv",
22 | "tsv"
23 | ],
24 | "author": "Carlos \"blakgeek\" Lawton",
25 | "license": "MIT",
26 | "bugs": {
27 | "url": "https://github.com/blakgeek/spreadit/issues"
28 | },
29 | "homepage": "https://github.com/blakgeek/spreadit#readme",
30 | "devDependencies": {
31 | "grunt": "^0.4.5",
32 | "grunt-angular-templates": "^1.0.3",
33 | "grunt-bower-concat": "^1.0.0",
34 | "grunt-concurrent": "^2.3.0",
35 | "grunt-contrib-clean": "^1.0.0",
36 | "grunt-contrib-concat": "^1.0.1",
37 | "grunt-contrib-copy": "^1.0.0",
38 | "grunt-contrib-sass": "^1.0.0",
39 | "grunt-contrib-uglify": "^1.0.1",
40 | "grunt-contrib-watch": "^1.0.0",
41 | "grunt-open": "^0.2.3",
42 | "grunt-serve": "^0.1.6",
43 | "load-grunt-tasks": "^3.5.0"
44 | }
45 | }
46 |
--------------------------------------------------------------------------------
/screenshot.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/blakgeek/spreadit/9d600a5f20031b719838cef4b33bcf9a57c015c5/screenshot.png
--------------------------------------------------------------------------------
/src/columnManager.html:
--------------------------------------------------------------------------------
1 |
5 |
6 | -
8 |
9 |
10 |
11 | - {{column.header}}
12 | -
13 | {{sample}}
14 |
15 |
16 |
17 |
18 |
19 | {{column.mapping.title}}
20 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
--------------------------------------------------------------------------------
/src/dropzone.html:
--------------------------------------------------------------------------------
1 |
9 |
10 |
Wanna Import a spreadsheet (Excel or CSV)?
11 |
Click here or drag and drop your file like it's hot.
12 |
13 |
14 |
15 |
--------------------------------------------------------------------------------
/src/module.js:
--------------------------------------------------------------------------------
1 | +function() {
2 |
3 | angular.module('bg.spreadit', []);
4 | }();
--------------------------------------------------------------------------------
/src/sass/_columnManager.scss:
--------------------------------------------------------------------------------
1 | $siPositiveColor: #52a552 !default;
2 | $siPositiveBorder: darken(adjust-hue($siPositiveColor, -10), 5%) !default;
3 |
4 | si-column-manager {
5 |
6 | ul {
7 | list-style: none;
8 | margin: 0;
9 | padding: 0;
10 | }
11 |
12 | position: fixed;
13 | top: 0;
14 | left: 0;
15 | bottom: 0;
16 | right: 0;
17 | visibility: hidden;
18 | background-color: rgba(white, .95);
19 | z-index: 2000;
20 |
21 | &.active {
22 | visibility: visible;
23 | }
24 |
25 | header {
26 |
27 | position: absolute;
28 | top: 0;
29 | right: 0;
30 | left: 0;
31 | margin: 10px auto;
32 | }
33 |
34 | footer {
35 |
36 | position: absolute;
37 | bottom: 0;
38 | right: 0;
39 | left: 0;
40 | margin: 10px auto;
41 | }
42 |
43 | .si-toggle {
44 | @include display(flex);
45 | @include align-items(center);
46 | white-space: nowrap;
47 |
48 | input[type="checkbox"] {
49 | @include appearance(none);
50 | display: none;
51 |
52 | &:checked + i {
53 | background-color: $siPositiveColor;
54 | &:after {
55 | right: 0;
56 | left: auto;
57 | }
58 | }
59 | }
60 |
61 | i {
62 | @include flex(0 0 40px);
63 | height: 25px;
64 | position: relative;
65 | background-color: #f0f0f0;
66 | border-radius: 25px;
67 | margin-right: 8px;
68 |
69 | &:after {
70 | content: '';
71 | display: block;
72 | background-color: white;
73 | border-radius: 20px;
74 | height: 21px;
75 | width: 21px;
76 | margin: 2px;
77 | position: absolute;
78 | left: 0;
79 | top: 0;
80 | }
81 | }
82 | }
83 |
84 | .si-column-manager-actions {
85 |
86 | @include display(flex);
87 | @include align-items(center);
88 | width: calc(100% - 40px);
89 | max-width: 800px;
90 |
91 |
92 | button {
93 | height: 40px;
94 | padding: 0 20px;
95 | font-size: inherit;
96 | font-family: inherit;
97 | }
98 |
99 | .si-has-header {
100 | margin-right: auto;
101 | }
102 |
103 | .si-close {
104 |
105 | line-height: 40px;
106 | width: 40px;
107 | text-align: center;
108 | border-radius: 4px;
109 | font-size: 24px;
110 | font-weight: bold;
111 | cursor: pointer;
112 |
113 | &:hover {
114 | background-color: rgba(black, .05);
115 | }
116 | }
117 |
118 | .si-import {
119 |
120 | background-color: $siPositiveColor;
121 | color: white;
122 | text-shadow: 0 1px 1px rgba(black, .03);
123 | border: 1px solid $siPositiveBorder;
124 | border-radius: 4px;
125 | }
126 |
127 | }
128 |
129 | header.si-column-manager-actions {
130 |
131 |
132 | }
133 |
134 | footer.si-column-manager-actions {
135 |
136 | @include justify-content(flex-end);
137 | }
138 |
139 | .si-column-manager-columns {
140 |
141 | left: 0;
142 | right: 0;
143 | top: 0;
144 | bottom: 0;
145 | position: absolute;
146 | margin: 60px auto 60px;
147 | width: calc(100% - 40px);
148 | max-width: 800px;
149 | counter-reset: column-counter;
150 | border-bottom: 1px solid #ccc;
151 | border-top: 1px solid #ccc;
152 | box-shadow: 0 0 20px -4px rgba(0,0,0,.2);
153 | overflow-y: auto;
154 | background-color: white;
155 |
156 | .si-column-manager-column {
157 | @include display(flex);
158 | border: 1px solid #ccc;
159 | border-bottom: none;
160 | //margin-bottom: 20px;
161 |
162 | &.si-column-ignored {
163 |
164 | .si-column-manager-samples {
165 | text-decoration: line-through;
166 | color: #ccc;
167 | }
168 | }
169 | }
170 | }
171 |
172 | .si-column-manager-samples {
173 |
174 | counter-reset: sample-counter;
175 | @include flex-grow(1);
176 | position: relative;
177 |
178 | .si-column-manager-sample-title {
179 | font-weight: bold;
180 | font-size: 20px;
181 |
182 | &:before {
183 | line-height: 40px !important;
184 | }
185 | }
186 |
187 | li:last-of-type {
188 | border-bottom: none !important;
189 | }
190 |
191 | .si-column-manager-sample-header {
192 |
193 | background-color: #e8e8e8;
194 | @include display(flex);
195 | @include align-items(center);
196 | border-bottom: 1px solid #ccc;
197 |
198 | &:before {
199 | @include flex(0 0 30px);
200 | background-color: #e8e8e8;
201 | display: block;
202 | line-height: 30px;
203 | text-align: center;
204 | margin-right: 10px;
205 | content: '\00a0';
206 | border-right: 1px solid #ccc;
207 | }
208 | &:after {
209 | display: block;
210 | content: counter(column-counter, upper-alpha);
211 | counter-increment: column-counter;
212 | text-align: center;
213 | @include flex-grow(1);
214 | }
215 | }
216 |
217 |
218 | .si-column-manager-sample {
219 | @include display(flex);
220 | @include align-items(center);
221 | border-bottom: 1px solid #ccc;
222 |
223 | &:before {
224 | @include flex(0 0 30px);
225 | background-color: #e8e8e8;
226 | display: block;
227 | line-height: 30px;
228 | text-align: center;
229 | content: counter(sample-counter, decimal);
230 | counter-increment: sample-counter;
231 | margin-right: 10px;
232 | border-right: 1px solid #ccc;
233 | font-size: 1rem;
234 | font-weight: normal;
235 | }
236 | }
237 | }
238 |
239 | .si-column-manager-editor {
240 | @include flex(0 0 300px);
241 | padding: 20px;
242 | position: relative;
243 |
244 | input {
245 | width: 100%;
246 | font-family: inherit;
247 | font-size: inherit;
248 | height: 40px;
249 | padding: 12px;
250 | box-sizing: border-box;
251 | }
252 |
253 | .select-group {
254 | width: 100%;
255 | box-sizing: border-box;
256 | margin-bottom: 10px;
257 | position: relative;
258 | @include display(flex);
259 | @include align-items(center);
260 | padding: 0 10px;
261 | border: 1px solid #ccc;
262 | background-color: white;
263 | color: black;
264 | border-radius: 3px;
265 | height: 40px;
266 |
267 | &:after {
268 | font-family: Arrows;
269 | content: '\e901';
270 | margin-left: auto;
271 | display: inline-block;
272 | @include flex(0 0 auto);
273 | }
274 |
275 | select {
276 | @include appearance(none);
277 | position: absolute;
278 | top: 0;
279 | left: 0;
280 | width: 100%;
281 | height: 100%;
282 | opacity: 0;
283 | }
284 | }
285 |
286 | label {
287 | margin-bottom: 6px;
288 | font-size: 20px;
289 | font-weight: bold;
290 | display: block;
291 | }
292 |
293 | &:after {
294 | background: linear-gradient(-45deg, white 9px, transparent 0), linear-gradient(-135deg, white 9px, transparent 0),
295 | linear-gradient(-45deg, #ccc 10px, transparent 0), linear-gradient(-135deg, #ccc 10px, transparent 0);
296 | background-position: left-bottom;
297 | background-repeat: repeat-y;
298 | background-size: 20px 20px;
299 | content: " ";
300 | display: block;
301 | position: absolute;
302 | top: 0;
303 | left: -20px;
304 | width: 20px;
305 | height: 100%;
306 | bottom: 0;
307 | }
308 | }
309 | }
--------------------------------------------------------------------------------
/src/sass/_dropzone.scss:
--------------------------------------------------------------------------------
1 | si-dropzone {
2 | @include display(flex);
3 | @include justify-content(center);
4 | @include align-items(center);
5 | height: 160px;
6 | border: 1px #a0a0a0 dashed;
7 | border-radius: 5px;
8 | width: calc(100% - 40px);
9 | max-width: 800px;
10 | margin: 20px auto 30px;
11 | box-sizing: border-box;
12 | position: relative;
13 | cursor: pointer;
14 | background-color: white;
15 | @include transition(box-shadow 350ms);
16 |
17 | &:hover {
18 | border-color: #303030;
19 | box-shadow: 0 0 20px -4px rgba(0,0,0,.4);
20 | }
21 |
22 | .si-icon {
23 | margin-left: 20px;
24 | @include flex(0 0 65px);
25 |
26 | path {
27 | fill: #303030;
28 | }
29 | }
30 |
31 | .message {
32 |
33 | margin-right: 20px;
34 | margin-left: 10px;
35 | color: #303030;
36 | font-weight: normal;
37 | cursor: inherit;
38 |
39 | h2 {
40 | font-size: 20px;
41 | margin: 0;
42 | }
43 |
44 | p {
45 | margin: 0;
46 | }
47 | }
48 |
49 | input[type="file"] {
50 | @include appearance(none);
51 | opacity: 0;
52 | position: absolute;
53 | top: 0;
54 | left: 0;
55 | width: 100% !important;
56 | height: 100% !important;
57 | cursor: inherit;
58 | }
59 | }
--------------------------------------------------------------------------------
/src/sass/bourbon/_bourbon-deprecated-upcoming.scss:
--------------------------------------------------------------------------------
1 | // The following features have been deprecated and will be removed in the next MAJOR version release
2 |
3 | @mixin inline-block {
4 | display: inline-block;
5 |
6 | @warn "The inline-block mixin is deprecated and will be removed in the next major version release";
7 | }
8 |
9 | @mixin button ($style: simple, $base-color: #4294f0, $text-size: inherit, $padding: 7px 18px) {
10 |
11 | @if type-of($style) == string and type-of($base-color) == color {
12 | @include buttonstyle($style, $base-color, $text-size, $padding);
13 | }
14 |
15 | @if type-of($style) == string and type-of($base-color) == number {
16 | $padding: $text-size;
17 | $text-size: $base-color;
18 | $base-color: #4294f0;
19 |
20 | @if $padding == inherit {
21 | $padding: 7px 18px;
22 | }
23 |
24 | @include buttonstyle($style, $base-color, $text-size, $padding);
25 | }
26 |
27 | @if type-of($style) == color and type-of($base-color) == color {
28 | $base-color: $style;
29 | $style: simple;
30 | @include buttonstyle($style, $base-color, $text-size, $padding);
31 | }
32 |
33 | @if type-of($style) == color and type-of($base-color) == number {
34 | $padding: $text-size;
35 | $text-size: $base-color;
36 | $base-color: $style;
37 | $style: simple;
38 |
39 | @if $padding == inherit {
40 | $padding: 7px 18px;
41 | }
42 |
43 | @include buttonstyle($style, $base-color, $text-size, $padding);
44 | }
45 |
46 | @if type-of($style) == number {
47 | $padding: $base-color;
48 | $text-size: $style;
49 | $base-color: #4294f0;
50 | $style: simple;
51 |
52 | @if $padding == #4294f0 {
53 | $padding: 7px 18px;
54 | }
55 |
56 | @include buttonstyle($style, $base-color, $text-size, $padding);
57 | }
58 |
59 | &:disabled {
60 | cursor: not-allowed;
61 | opacity: 0.5;
62 | }
63 |
64 | @warn "The button mixin is deprecated and will be removed in the next major version release";
65 | }
66 |
67 | // Selector Style Button
68 | @mixin buttonstyle($type, $b-color, $t-size, $pad) {
69 | // Grayscale button
70 | @if $type == simple and $b-color == grayscale($b-color) {
71 | @include simple($b-color, true, $t-size, $pad);
72 | }
73 |
74 | @if $type == shiny and $b-color == grayscale($b-color) {
75 | @include shiny($b-color, true, $t-size, $pad);
76 | }
77 |
78 | @if $type == pill and $b-color == grayscale($b-color) {
79 | @include pill($b-color, true, $t-size, $pad);
80 | }
81 |
82 | @if $type == flat and $b-color == grayscale($b-color) {
83 | @include flat($b-color, true, $t-size, $pad);
84 | }
85 |
86 | // Colored button
87 | @if $type == simple {
88 | @include simple($b-color, false, $t-size, $pad);
89 | }
90 |
91 | @else if $type == shiny {
92 | @include shiny($b-color, false, $t-size, $pad);
93 | }
94 |
95 | @else if $type == pill {
96 | @include pill($b-color, false, $t-size, $pad);
97 | }
98 |
99 | @else if $type == flat {
100 | @include flat($b-color, false, $t-size, $pad);
101 | }
102 | }
103 |
104 | // Simple Button
105 | @mixin simple($base-color, $grayscale: false, $textsize: inherit, $padding: 7px 18px) {
106 | $color: hsl(0, 0, 100%);
107 | $border: adjust-color($base-color, $saturation: 9%, $lightness: -14%);
108 | $inset-shadow: adjust-color($base-color, $saturation: -8%, $lightness: 15%);
109 | $stop-gradient: adjust-color($base-color, $saturation: 9%, $lightness: -11%);
110 | $text-shadow: adjust-color($base-color, $saturation: 15%, $lightness: -18%);
111 |
112 | @if is-light($base-color) {
113 | $color: hsl(0, 0, 20%);
114 | $text-shadow: adjust-color($base-color, $saturation: 10%, $lightness: 4%);
115 | }
116 |
117 | @if $grayscale == true {
118 | $border: grayscale($border);
119 | $inset-shadow: grayscale($inset-shadow);
120 | $stop-gradient: grayscale($stop-gradient);
121 | $text-shadow: grayscale($text-shadow);
122 | }
123 |
124 | border: 1px solid $border;
125 | border-radius: 3px;
126 | box-shadow: inset 0 1px 0 0 $inset-shadow;
127 | color: $color;
128 | display: inline-block;
129 | font-size: $textsize;
130 | font-weight: bold;
131 | @include linear-gradient ($base-color, $stop-gradient);
132 | padding: $padding;
133 | text-decoration: none;
134 | text-shadow: 0 1px 0 $text-shadow;
135 | background-clip: padding-box;
136 |
137 | &:hover:not(:disabled) {
138 | $base-color-hover: adjust-color($base-color, $saturation: -4%, $lightness: -5%);
139 | $inset-shadow-hover: adjust-color($base-color, $saturation: -7%, $lightness: 5%);
140 | $stop-gradient-hover: adjust-color($base-color, $saturation: 8%, $lightness: -14%);
141 |
142 | @if $grayscale == true {
143 | $base-color-hover: grayscale($base-color-hover);
144 | $inset-shadow-hover: grayscale($inset-shadow-hover);
145 | $stop-gradient-hover: grayscale($stop-gradient-hover);
146 | }
147 |
148 | @include linear-gradient ($base-color-hover, $stop-gradient-hover);
149 |
150 | box-shadow: inset 0 1px 0 0 $inset-shadow-hover;
151 | cursor: pointer;
152 | }
153 |
154 | &:active:not(:disabled),
155 | &:focus:not(:disabled) {
156 | $border-active: adjust-color($base-color, $saturation: 9%, $lightness: -14%);
157 | $inset-shadow-active: adjust-color($base-color, $saturation: 7%, $lightness: -17%);
158 |
159 | @if $grayscale == true {
160 | $border-active: grayscale($border-active);
161 | $inset-shadow-active: grayscale($inset-shadow-active);
162 | }
163 |
164 | border: 1px solid $border-active;
165 | box-shadow: inset 0 0 8px 4px $inset-shadow-active, inset 0 0 8px 4px $inset-shadow-active;
166 | }
167 | }
168 |
169 | // Shiny Button
170 | @mixin shiny($base-color, $grayscale: false, $textsize: inherit, $padding: 7px 18px) {
171 | $color: hsl(0, 0, 100%);
172 | $border: adjust-color($base-color, $red: -117, $green: -111, $blue: -81);
173 | $border-bottom: adjust-color($base-color, $red: -126, $green: -127, $blue: -122);
174 | $fourth-stop: adjust-color($base-color, $red: -79, $green: -70, $blue: -46);
175 | $inset-shadow: adjust-color($base-color, $red: 37, $green: 29, $blue: 12);
176 | $second-stop: adjust-color($base-color, $red: -56, $green: -50, $blue: -33);
177 | $text-shadow: adjust-color($base-color, $red: -140, $green: -141, $blue: -114);
178 | $third-stop: adjust-color($base-color, $red: -86, $green: -75, $blue: -48);
179 |
180 | @if is-light($base-color) {
181 | $color: hsl(0, 0, 20%);
182 | $text-shadow: adjust-color($base-color, $saturation: 10%, $lightness: 4%);
183 | }
184 |
185 | @if $grayscale == true {
186 | $border: grayscale($border);
187 | $border-bottom: grayscale($border-bottom);
188 | $fourth-stop: grayscale($fourth-stop);
189 | $inset-shadow: grayscale($inset-shadow);
190 | $second-stop: grayscale($second-stop);
191 | $text-shadow: grayscale($text-shadow);
192 | $third-stop: grayscale($third-stop);
193 | }
194 |
195 | @include linear-gradient(top, $base-color 0%, $second-stop 50%, $third-stop 50%, $fourth-stop 100%);
196 |
197 | border: 1px solid $border;
198 | border-bottom: 1px solid $border-bottom;
199 | border-radius: 5px;
200 | box-shadow: inset 0 1px 0 0 $inset-shadow;
201 | color: $color;
202 | display: inline-block;
203 | font-size: $textsize;
204 | font-weight: bold;
205 | padding: $padding;
206 | text-align: center;
207 | text-decoration: none;
208 | text-shadow: 0 -1px 1px $text-shadow;
209 |
210 | &:hover:not(:disabled) {
211 | $first-stop-hover: adjust-color($base-color, $red: -13, $green: -15, $blue: -18);
212 | $second-stop-hover: adjust-color($base-color, $red: -66, $green: -62, $blue: -51);
213 | $third-stop-hover: adjust-color($base-color, $red: -93, $green: -85, $blue: -66);
214 | $fourth-stop-hover: adjust-color($base-color, $red: -86, $green: -80, $blue: -63);
215 |
216 | @if $grayscale == true {
217 | $first-stop-hover: grayscale($first-stop-hover);
218 | $second-stop-hover: grayscale($second-stop-hover);
219 | $third-stop-hover: grayscale($third-stop-hover);
220 | $fourth-stop-hover: grayscale($fourth-stop-hover);
221 | }
222 |
223 | @include linear-gradient(top, $first-stop-hover 0%,
224 | $second-stop-hover 50%,
225 | $third-stop-hover 50%,
226 | $fourth-stop-hover 100%);
227 | cursor: pointer;
228 | }
229 |
230 | &:active:not(:disabled),
231 | &:focus:not(:disabled) {
232 | $inset-shadow-active: adjust-color($base-color, $red: -111, $green: -116, $blue: -122);
233 |
234 | @if $grayscale == true {
235 | $inset-shadow-active: grayscale($inset-shadow-active);
236 | }
237 |
238 | box-shadow: inset 0 0 20px 0 $inset-shadow-active;
239 | }
240 | }
241 |
242 | // Pill Button
243 | @mixin pill($base-color, $grayscale: false, $textsize: inherit, $padding: 7px 18px) {
244 | $color: hsl(0, 0, 100%);
245 | $border-bottom: adjust-color($base-color, $hue: 8, $saturation: -11%, $lightness: -26%);
246 | $border-sides: adjust-color($base-color, $hue: 4, $saturation: -21%, $lightness: -21%);
247 | $border-top: adjust-color($base-color, $hue: -1, $saturation: -30%, $lightness: -15%);
248 | $inset-shadow: adjust-color($base-color, $hue: -1, $saturation: -1%, $lightness: 7%);
249 | $stop-gradient: adjust-color($base-color, $hue: 8, $saturation: 14%, $lightness: -10%);
250 | $text-shadow: adjust-color($base-color, $hue: 5, $saturation: -19%, $lightness: -15%);
251 |
252 | @if is-light($base-color) {
253 | $color: hsl(0, 0, 20%);
254 | $text-shadow: adjust-color($base-color, $saturation: 10%, $lightness: 4%);
255 | }
256 |
257 | @if $grayscale == true {
258 | $border-bottom: grayscale($border-bottom);
259 | $border-sides: grayscale($border-sides);
260 | $border-top: grayscale($border-top);
261 | $inset-shadow: grayscale($inset-shadow);
262 | $stop-gradient: grayscale($stop-gradient);
263 | $text-shadow: grayscale($text-shadow);
264 | }
265 |
266 | border: 1px solid $border-top;
267 | border-color: $border-top $border-sides $border-bottom;
268 | border-radius: 16px;
269 | box-shadow: inset 0 1px 0 0 $inset-shadow;
270 | color: $color;
271 | display: inline-block;
272 | font-size: $textsize;
273 | font-weight: normal;
274 | line-height: 1;
275 | @include linear-gradient ($base-color, $stop-gradient);
276 | padding: $padding;
277 | text-align: center;
278 | text-decoration: none;
279 | text-shadow: 0 -1px 1px $text-shadow;
280 | background-clip: padding-box;
281 |
282 | &:hover:not(:disabled) {
283 | $base-color-hover: adjust-color($base-color, $lightness: -4.5%);
284 | $border-bottom: adjust-color($base-color, $hue: 8, $saturation: 13.5%, $lightness: -32%);
285 | $border-sides: adjust-color($base-color, $hue: 4, $saturation: -2%, $lightness: -27%);
286 | $border-top: adjust-color($base-color, $hue: -1, $saturation: -17%, $lightness: -21%);
287 | $inset-shadow-hover: adjust-color($base-color, $saturation: -1%, $lightness: 3%);
288 | $stop-gradient-hover: adjust-color($base-color, $hue: 8, $saturation: -4%, $lightness: -15.5%);
289 | $text-shadow-hover: adjust-color($base-color, $hue: 5, $saturation: -5%, $lightness: -22%);
290 |
291 | @if $grayscale == true {
292 | $base-color-hover: grayscale($base-color-hover);
293 | $border-bottom: grayscale($border-bottom);
294 | $border-sides: grayscale($border-sides);
295 | $border-top: grayscale($border-top);
296 | $inset-shadow-hover: grayscale($inset-shadow-hover);
297 | $stop-gradient-hover: grayscale($stop-gradient-hover);
298 | $text-shadow-hover: grayscale($text-shadow-hover);
299 | }
300 |
301 | @include linear-gradient ($base-color-hover, $stop-gradient-hover);
302 |
303 | background-clip: padding-box;
304 | border: 1px solid $border-top;
305 | border-color: $border-top $border-sides $border-bottom;
306 | box-shadow: inset 0 1px 0 0 $inset-shadow-hover;
307 | cursor: pointer;
308 | text-shadow: 0 -1px 1px $text-shadow-hover;
309 | }
310 |
311 | &:active:not(:disabled),
312 | &:focus:not(:disabled) {
313 | $active-color: adjust-color($base-color, $hue: 4, $saturation: -12%, $lightness: -10%);
314 | $border-active: adjust-color($base-color, $hue: 6, $saturation: -2.5%, $lightness: -30%);
315 | $border-bottom-active: adjust-color($base-color, $hue: 11, $saturation: 6%, $lightness: -31%);
316 | $inset-shadow-active: adjust-color($base-color, $hue: 9, $saturation: 2%, $lightness: -21.5%);
317 | $text-shadow-active: adjust-color($base-color, $hue: 5, $saturation: -12%, $lightness: -21.5%);
318 |
319 | @if $grayscale == true {
320 | $active-color: grayscale($active-color);
321 | $border-active: grayscale($border-active);
322 | $border-bottom-active: grayscale($border-bottom-active);
323 | $inset-shadow-active: grayscale($inset-shadow-active);
324 | $text-shadow-active: grayscale($text-shadow-active);
325 | }
326 |
327 | background: $active-color;
328 | border: 1px solid $border-active;
329 | border-bottom: 1px solid $border-bottom-active;
330 | box-shadow: inset 0 0 6px 3px $inset-shadow-active;
331 | text-shadow: 0 -1px 1px $text-shadow-active;
332 | }
333 | }
334 |
335 | // Flat Button
336 | @mixin flat($base-color, $grayscale: false, $textsize: inherit, $padding: 7px 18px) {
337 | $color: hsl(0, 0, 100%);
338 |
339 | @if is-light($base-color) {
340 | $color: hsl(0, 0, 20%);
341 | }
342 |
343 | background-color: $base-color;
344 | border-radius: 3px;
345 | border: 0;
346 | color: $color;
347 | display: inline-block;
348 | font-size: $textsize;
349 | font-weight: bold;
350 | padding: $padding;
351 | text-decoration: none;
352 | background-clip: padding-box;
353 |
354 | &:hover:not(:disabled){
355 | $base-color-hover: adjust-color($base-color, $saturation: 4%, $lightness: 5%);
356 |
357 | @if $grayscale == true {
358 | $base-color-hover: grayscale($base-color-hover);
359 | }
360 |
361 | background-color: $base-color-hover;
362 | cursor: pointer;
363 | }
364 |
365 | &:active:not(:disabled),
366 | &:focus:not(:disabled) {
367 | $base-color-active: adjust-color($base-color, $saturation: -4%, $lightness: -5%);
368 |
369 | @if $grayscale == true {
370 | $base-color-active: grayscale($base-color-active);
371 | }
372 |
373 | background-color: $base-color-active;
374 | cursor: pointer;
375 | }
376 | }
377 |
378 | // Flexible grid
379 | @function flex-grid($columns, $container-columns: $fg-max-columns) {
380 | $width: $columns * $fg-column + ($columns - 1) * $fg-gutter;
381 | $container-width: $container-columns * $fg-column + ($container-columns - 1) * $fg-gutter;
382 | @return percentage($width / $container-width);
383 |
384 | @warn "The flex-grid function is deprecated and will be removed in the next major version release";
385 | }
386 |
387 | // Flexible gutter
388 | @function flex-gutter($container-columns: $fg-max-columns, $gutter: $fg-gutter) {
389 | $container-width: $container-columns * $fg-column + ($container-columns - 1) * $fg-gutter;
390 | @return percentage($gutter / $container-width);
391 |
392 | @warn "The flex-gutter function is deprecated and will be removed in the next major version release";
393 | }
394 |
395 | @function grid-width($n) {
396 | @return $n * $gw-column + ($n - 1) * $gw-gutter;
397 |
398 | @warn "The grid-width function is deprecated and will be removed in the next major version release";
399 | }
400 |
401 | @function golden-ratio($value, $increment) {
402 | @return modular-scale($increment, $value, $ratio: $golden);
403 |
404 | @warn "The golden-ratio function is deprecated and will be removed in the next major version release. Please use the modular-scale function, instead.";
405 | }
406 |
407 | @mixin box-sizing($box) {
408 | @include prefixer(box-sizing, $box, webkit moz spec);
409 |
410 | @warn "The box-sizing mixin is deprecated and will be removed in the next major version release. This property can now be used un-prefixed.";
411 | }
412 |
--------------------------------------------------------------------------------
/src/sass/bourbon/_bourbon.scss:
--------------------------------------------------------------------------------
1 | // Bourbon 4.2.6
2 | // http://bourbon.io
3 | // Copyright 2011-2015 thoughtbot, inc.
4 | // MIT License
5 |
6 | @import "settings/prefixer";
7 | @import "settings/px-to-em";
8 | @import "settings/asset-pipeline";
9 |
10 | @import "functions/assign-inputs";
11 | @import "functions/contains";
12 | @import "functions/contains-falsy";
13 | @import "functions/is-length";
14 | @import "functions/is-light";
15 | @import "functions/is-number";
16 | @import "functions/is-size";
17 | @import "functions/px-to-em";
18 | @import "functions/px-to-rem";
19 | @import "functions/shade";
20 | @import "functions/strip-units";
21 | @import "functions/tint";
22 | @import "functions/transition-property-name";
23 | @import "functions/unpack";
24 | @import "functions/modular-scale";
25 |
26 | @import "helpers/convert-units";
27 | @import "helpers/directional-values";
28 | @import "helpers/font-source-declaration";
29 | @import "helpers/gradient-positions-parser";
30 | @import "helpers/linear-angle-parser";
31 | @import "helpers/linear-gradient-parser";
32 | @import "helpers/linear-positions-parser";
33 | @import "helpers/linear-side-corner-parser";
34 | @import "helpers/radial-arg-parser";
35 | @import "helpers/radial-positions-parser";
36 | @import "helpers/radial-gradient-parser";
37 | @import "helpers/render-gradients";
38 | @import "helpers/shape-size-stripper";
39 | @import "helpers/str-to-num";
40 |
41 | @import "css3/animation";
42 | @import "css3/appearance";
43 | @import "css3/backface-visibility";
44 | @import "css3/background";
45 | @import "css3/background-image";
46 | @import "css3/border-image";
47 | @import "css3/calc";
48 | @import "css3/columns";
49 | @import "css3/filter";
50 | @import "css3/flex-box";
51 | @import "css3/font-face";
52 | @import "css3/font-feature-settings";
53 | @import "css3/hidpi-media-query";
54 | @import "css3/hyphens";
55 | @import "css3/image-rendering";
56 | @import "css3/keyframes";
57 | @import "css3/linear-gradient";
58 | @import "css3/perspective";
59 | @import "css3/placeholder";
60 | @import "css3/radial-gradient";
61 | @import "css3/selection";
62 | @import "css3/text-decoration";
63 | @import "css3/transform";
64 | @import "css3/transition";
65 | @import "css3/user-select";
66 |
67 | @import "addons/border-color";
68 | @import "addons/border-radius";
69 | @import "addons/border-style";
70 | @import "addons/border-width";
71 | @import "addons/buttons";
72 | @import "addons/clearfix";
73 | @import "addons/ellipsis";
74 | @import "addons/font-stacks";
75 | @import "addons/hide-text";
76 | @import "addons/margin";
77 | @import "addons/padding";
78 | @import "addons/position";
79 | @import "addons/prefixer";
80 | @import "addons/retina-image";
81 | @import "addons/size";
82 | @import "addons/text-inputs";
83 | @import "addons/timing-functions";
84 | @import "addons/triangle";
85 | @import "addons/word-wrap";
86 |
87 | @import "bourbon-deprecated-upcoming";
88 |
--------------------------------------------------------------------------------
/src/sass/bourbon/addons/_border-color.scss:
--------------------------------------------------------------------------------
1 | @charset "UTF-8";
2 |
3 | /// Provides a quick method for targeting `border-color` on specific sides of a box. Use a `null` value to “skip” a side.
4 | ///
5 | /// @param {Arglist} $vals
6 | /// List of arguments
7 | ///
8 | /// @example scss - Usage
9 | /// .element {
10 | /// @include border-color(#a60b55 #76cd9c null #e8ae1a);
11 | /// }
12 | ///
13 | /// @example css - CSS Output
14 | /// .element {
15 | /// border-left-color: #e8ae1a;
16 | /// border-right-color: #76cd9c;
17 | /// border-top-color: #a60b55;
18 | /// }
19 | ///
20 | /// @require {mixin} directional-property
21 | ///
22 | /// @output `border-color`
23 |
24 | @mixin border-color($vals...) {
25 | @include directional-property(border, color, $vals...);
26 | }
27 |
--------------------------------------------------------------------------------
/src/sass/bourbon/addons/_border-radius.scss:
--------------------------------------------------------------------------------
1 | @charset "UTF-8";
2 |
3 | /// Provides a quick method for targeting `border-radius` on both corners on the side of a box.
4 | ///
5 | /// @param {Number} $radii
6 | /// List of arguments
7 | ///
8 | /// @example scss - Usage
9 | /// .element-one {
10 | /// @include border-top-radius(5px);
11 | /// }
12 | ///
13 | /// .element-two {
14 | /// @include border-left-radius(3px);
15 | /// }
16 | ///
17 | /// @example css - CSS Output
18 | /// .element-one {
19 | /// border-top-left-radius: 5px;
20 | /// border-top-right-radius: 5px;
21 | /// }
22 | ///
23 | /// .element-two {
24 | /// border-bottom-left-radius: 3px;
25 | /// border-top-left-radius: 3px;
26 | /// }
27 | ///
28 | /// @output `border-radius`
29 |
30 | @mixin border-top-radius($radii) {
31 | border-top-left-radius: $radii;
32 | border-top-right-radius: $radii;
33 | }
34 |
35 | @mixin border-right-radius($radii) {
36 | border-bottom-right-radius: $radii;
37 | border-top-right-radius: $radii;
38 | }
39 |
40 | @mixin border-bottom-radius($radii) {
41 | border-bottom-left-radius: $radii;
42 | border-bottom-right-radius: $radii;
43 | }
44 |
45 | @mixin border-left-radius($radii) {
46 | border-bottom-left-radius: $radii;
47 | border-top-left-radius: $radii;
48 | }
49 |
--------------------------------------------------------------------------------
/src/sass/bourbon/addons/_border-style.scss:
--------------------------------------------------------------------------------
1 | @charset "UTF-8";
2 |
3 | /// Provides a quick method for targeting `border-style` on specific sides of a box. Use a `null` value to “skip” a side.
4 | ///
5 | /// @param {Arglist} $vals
6 | /// List of arguments
7 | ///
8 | /// @example scss - Usage
9 | /// .element {
10 | /// @include border-style(dashed null solid);
11 | /// }
12 | ///
13 | /// @example css - CSS Output
14 | /// .element {
15 | /// border-bottom-style: solid;
16 | /// border-top-style: dashed;
17 | /// }
18 | ///
19 | /// @require {mixin} directional-property
20 | ///
21 | /// @output `border-style`
22 |
23 | @mixin border-style($vals...) {
24 | @include directional-property(border, style, $vals...);
25 | }
26 |
--------------------------------------------------------------------------------
/src/sass/bourbon/addons/_border-width.scss:
--------------------------------------------------------------------------------
1 | @charset "UTF-8";
2 |
3 | /// Provides a quick method for targeting `border-width` on specific sides of a box. Use a `null` value to “skip” a side.
4 | ///
5 | /// @param {Arglist} $vals
6 | /// List of arguments
7 | ///
8 | /// @example scss - Usage
9 | /// .element {
10 | /// @include border-width(1em null 20px);
11 | /// }
12 | ///
13 | /// @example css - CSS Output
14 | /// .element {
15 | /// border-bottom-width: 20px;
16 | /// border-top-width: 1em;
17 | /// }
18 | ///
19 | /// @require {mixin} directional-property
20 | ///
21 | /// @output `border-width`
22 |
23 | @mixin border-width($vals...) {
24 | @include directional-property(border, width, $vals...);
25 | }
26 |
--------------------------------------------------------------------------------
/src/sass/bourbon/addons/_buttons.scss:
--------------------------------------------------------------------------------
1 | @charset "UTF-8";
2 |
3 | /// Generates variables for all buttons. Please note that you must use interpolation on the variable: `#{$all-buttons}`.
4 | ///
5 | /// @example scss - Usage
6 | /// #{$all-buttons} {
7 | /// background-color: #f00;
8 | /// }
9 | ///
10 | /// #{$all-buttons-focus},
11 | /// #{$all-buttons-hover} {
12 | /// background-color: #0f0;
13 | /// }
14 | ///
15 | /// #{$all-buttons-active} {
16 | /// background-color: #00f;
17 | /// }
18 | ///
19 | /// @example css - CSS Output
20 | /// button,
21 | /// input[type="button"],
22 | /// input[type="reset"],
23 | /// input[type="submit"] {
24 | /// background-color: #f00;
25 | /// }
26 | ///
27 | /// button:focus,
28 | /// input[type="button"]:focus,
29 | /// input[type="reset"]:focus,
30 | /// input[type="submit"]:focus,
31 | /// button:hover,
32 | /// input[type="button"]:hover,
33 | /// input[type="reset"]:hover,
34 | /// input[type="submit"]:hover {
35 | /// background-color: #0f0;
36 | /// }
37 | ///
38 | /// button:active,
39 | /// input[type="button"]:active,
40 | /// input[type="reset"]:active,
41 | /// input[type="submit"]:active {
42 | /// background-color: #00f;
43 | /// }
44 | ///
45 | /// @require assign-inputs
46 | ///
47 | /// @type List
48 | ///
49 | /// @todo Remove double assigned variables (Lines 59–62) in v5.0.0
50 |
51 | $buttons-list: 'button',
52 | 'input[type="button"]',
53 | 'input[type="reset"]',
54 | 'input[type="submit"]';
55 |
56 | $all-buttons: assign-inputs($buttons-list);
57 | $all-buttons-active: assign-inputs($buttons-list, active);
58 | $all-buttons-focus: assign-inputs($buttons-list, focus);
59 | $all-buttons-hover: assign-inputs($buttons-list, hover);
60 |
61 | $all-button-inputs: $all-buttons;
62 | $all-button-inputs-active: $all-buttons-active;
63 | $all-button-inputs-focus: $all-buttons-focus;
64 | $all-button-inputs-hover: $all-buttons-hover;
65 |
--------------------------------------------------------------------------------
/src/sass/bourbon/addons/_clearfix.scss:
--------------------------------------------------------------------------------
1 | @charset "UTF-8";
2 |
3 | /// Provides an easy way to include a clearfix for containing floats.
4 | ///
5 | /// @link http://cssmojo.com/latest_new_clearfix_so_far/
6 | ///
7 | /// @example scss - Usage
8 | /// .element {
9 | /// @include clearfix;
10 | /// }
11 | ///
12 | /// @example css - CSS Output
13 | /// .element::after {
14 | /// clear: both;
15 | /// content: "";
16 | /// display: table;
17 | /// }
18 |
19 | @mixin clearfix {
20 | &::after {
21 | clear: both;
22 | content: "";
23 | display: table;
24 | }
25 | }
26 |
--------------------------------------------------------------------------------
/src/sass/bourbon/addons/_ellipsis.scss:
--------------------------------------------------------------------------------
1 | @charset "UTF-8";
2 |
3 | /// Truncates text and adds an ellipsis to represent overflow.
4 | ///
5 | /// @param {Number} $width [100%]
6 | /// Max-width for the string to respect before being truncated
7 | ///
8 | /// @example scss - Usage
9 | /// .element {
10 | /// @include ellipsis;
11 | /// }
12 | ///
13 | /// @example css - CSS Output
14 | /// .element {
15 | /// display: inline-block;
16 | /// max-width: 100%;
17 | /// overflow: hidden;
18 | /// text-overflow: ellipsis;
19 | /// white-space: nowrap;
20 | /// word-wrap: normal;
21 | /// }
22 |
23 | @mixin ellipsis($width: 100%) {
24 | display: inline-block;
25 | max-width: $width;
26 | overflow: hidden;
27 | text-overflow: ellipsis;
28 | white-space: nowrap;
29 | word-wrap: normal;
30 | }
31 |
--------------------------------------------------------------------------------
/src/sass/bourbon/addons/_font-stacks.scss:
--------------------------------------------------------------------------------
1 | @charset "UTF-8";
2 |
3 | /// Georgia font stack.
4 | ///
5 | /// @type List
6 |
7 | $georgia: "Georgia", "Cambria", "Times New Roman", "Times", serif;
8 |
9 | /// Helvetica font stack.
10 | ///
11 | /// @type List
12 |
13 | $helvetica: "Helvetica Neue", "Helvetica", "Roboto", "Arial", sans-serif;
14 |
15 | /// Lucida Grande font stack.
16 | ///
17 | /// @type List
18 |
19 | $lucida-grande: "Lucida Grande", "Tahoma", "Verdana", "Arial", sans-serif;
20 |
21 | /// Monospace font stack.
22 | ///
23 | /// @type List
24 |
25 | $monospace: "Bitstream Vera Sans Mono", "Consolas", "Courier", monospace;
26 |
27 | /// Verdana font stack.
28 | ///
29 | /// @type List
30 |
31 | $verdana: "Verdana", "Geneva", sans-serif;
32 |
--------------------------------------------------------------------------------
/src/sass/bourbon/addons/_hide-text.scss:
--------------------------------------------------------------------------------
1 | /// Hides the text in an element, commonly used to show an image. Some elements will need block-level styles applied.
2 | ///
3 | /// @link http://zeldman.com/2012/03/01/replacing-the-9999px-hack-new-image-replacement
4 | ///
5 | /// @example scss - Usage
6 | /// .element {
7 | /// @include hide-text;
8 | /// }
9 | ///
10 | /// @example css - CSS Output
11 | /// .element {
12 | /// overflow: hidden;
13 | /// text-indent: 101%;
14 | /// white-space: nowrap;
15 | /// }
16 | ///
17 | /// @todo Remove height argument in v5.0.0
18 |
19 | @mixin hide-text($height: null) {
20 | overflow: hidden;
21 | text-indent: 101%;
22 | white-space: nowrap;
23 |
24 | @if $height {
25 | @warn "The `hide-text` mixin has changed and no longer requires a height. The height argument will no longer be accepted in v5.0.0";
26 | }
27 | }
28 |
--------------------------------------------------------------------------------
/src/sass/bourbon/addons/_margin.scss:
--------------------------------------------------------------------------------
1 | @charset "UTF-8";
2 |
3 | /// Provides a quick method for targeting `margin` on specific sides of a box. Use a `null` value to “skip” a side.
4 | ///
5 | /// @param {Arglist} $vals
6 | /// List of arguments
7 | ///
8 | /// @example scss - Usage
9 | /// .element {
10 | /// @include margin(null 10px 3em 20vh);
11 | /// }
12 | ///
13 | /// @example css - CSS Output
14 | /// .element {
15 | /// margin-bottom: 3em;
16 | /// margin-left: 20vh;
17 | /// margin-right: 10px;
18 | /// }
19 | ///
20 | /// @require {mixin} directional-property
21 | ///
22 | /// @output `margin`
23 |
24 | @mixin margin($vals...) {
25 | @include directional-property(margin, false, $vals...);
26 | }
27 |
--------------------------------------------------------------------------------
/src/sass/bourbon/addons/_padding.scss:
--------------------------------------------------------------------------------
1 | @charset "UTF-8";
2 |
3 | /// Provides a quick method for targeting `padding` on specific sides of a box. Use a `null` value to “skip” a side.
4 | ///
5 | /// @param {Arglist} $vals
6 | /// List of arguments
7 | ///
8 | /// @example scss - Usage
9 | /// .element {
10 | /// @include padding(12vh null 10px 5%);
11 | /// }
12 | ///
13 | /// @example css - CSS Output
14 | /// .element {
15 | /// padding-bottom: 10px;
16 | /// padding-left: 5%;
17 | /// padding-top: 12vh;
18 | /// }
19 | ///
20 | /// @require {mixin} directional-property
21 | ///
22 | /// @output `padding`
23 |
24 | @mixin padding($vals...) {
25 | @include directional-property(padding, false, $vals...);
26 | }
27 |
--------------------------------------------------------------------------------
/src/sass/bourbon/addons/_position.scss:
--------------------------------------------------------------------------------
1 | @charset "UTF-8";
2 |
3 | /// Provides a quick method for setting an element’s position. Use a `null` value to “skip” a side.
4 | ///
5 | /// @param {Position} $position [relative]
6 | /// A CSS position value
7 | ///
8 | /// @param {Arglist} $coordinates [null null null null]
9 | /// List of values that correspond to the 4-value syntax for the edges of a box
10 | ///
11 | /// @example scss - Usage
12 | /// .element {
13 | /// @include position(absolute, 0 null null 10em);
14 | /// }
15 | ///
16 | /// @example css - CSS Output
17 | /// .element {
18 | /// left: 10em;
19 | /// position: absolute;
20 | /// top: 0;
21 | /// }
22 | ///
23 | /// @require {function} is-length
24 | /// @require {function} unpack
25 |
26 | @mixin position($position: relative, $coordinates: null null null null) {
27 | @if type-of($position) == list {
28 | $coordinates: $position;
29 | $position: relative;
30 | }
31 |
32 | $coordinates: unpack($coordinates);
33 |
34 | $offsets: (
35 | top: nth($coordinates, 1),
36 | right: nth($coordinates, 2),
37 | bottom: nth($coordinates, 3),
38 | left: nth($coordinates, 4)
39 | );
40 |
41 | position: $position;
42 |
43 | @each $offset, $value in $offsets {
44 | @if is-length($value) {
45 | #{$offset}: $value;
46 | }
47 | }
48 | }
49 |
--------------------------------------------------------------------------------
/src/sass/bourbon/addons/_prefixer.scss:
--------------------------------------------------------------------------------
1 | @charset "UTF-8";
2 |
3 | /// A mixin for generating vendor prefixes on non-standardized properties.
4 | ///
5 | /// @param {String} $property
6 | /// Property to prefix
7 | ///
8 | /// @param {*} $value
9 | /// Value to use
10 | ///
11 | /// @param {List} $prefixes
12 | /// Prefixes to define
13 | ///
14 | /// @example scss - Usage
15 | /// .element {
16 | /// @include prefixer(border-radius, 10px, webkit ms spec);
17 | /// }
18 | ///
19 | /// @example css - CSS Output
20 | /// .element {
21 | /// -webkit-border-radius: 10px;
22 | /// -moz-border-radius: 10px;
23 | /// border-radius: 10px;
24 | /// }
25 | ///
26 | /// @require {variable} $prefix-for-webkit
27 | /// @require {variable} $prefix-for-mozilla
28 | /// @require {variable} $prefix-for-microsoft
29 | /// @require {variable} $prefix-for-opera
30 | /// @require {variable} $prefix-for-spec
31 |
32 | @mixin prefixer($property, $value, $prefixes) {
33 | @each $prefix in $prefixes {
34 | @if $prefix == webkit {
35 | @if $prefix-for-webkit {
36 | -webkit-#{$property}: $value;
37 | }
38 | } @else if $prefix == moz {
39 | @if $prefix-for-mozilla {
40 | -moz-#{$property}: $value;
41 | }
42 | } @else if $prefix == ms {
43 | @if $prefix-for-microsoft {
44 | -ms-#{$property}: $value;
45 | }
46 | } @else if $prefix == o {
47 | @if $prefix-for-opera {
48 | -o-#{$property}: $value;
49 | }
50 | } @else if $prefix == spec {
51 | @if $prefix-for-spec {
52 | #{$property}: $value;
53 | }
54 | } @else {
55 | @warn "Unrecognized prefix: #{$prefix}";
56 | }
57 | }
58 | }
59 |
60 | @mixin disable-prefix-for-all() {
61 | $prefix-for-webkit: false !global;
62 | $prefix-for-mozilla: false !global;
63 | $prefix-for-microsoft: false !global;
64 | $prefix-for-opera: false !global;
65 | $prefix-for-spec: false !global;
66 | }
67 |
--------------------------------------------------------------------------------
/src/sass/bourbon/addons/_retina-image.scss:
--------------------------------------------------------------------------------
1 | @mixin retina-image($filename, $background-size, $extension: png, $retina-filename: null, $retina-suffix: _2x, $asset-pipeline: $asset-pipeline) {
2 | @if $asset-pipeline {
3 | background-image: image-url("#{$filename}.#{$extension}");
4 | } @else {
5 | background-image: url("#{$filename}.#{$extension}");
6 | }
7 |
8 | @include hidpi {
9 | @if $asset-pipeline {
10 | @if $retina-filename {
11 | background-image: image-url("#{$retina-filename}.#{$extension}");
12 | } @else {
13 | background-image: image-url("#{$filename}#{$retina-suffix}.#{$extension}");
14 | }
15 | } @else {
16 | @if $retina-filename {
17 | background-image: url("#{$retina-filename}.#{$extension}");
18 | } @else {
19 | background-image: url("#{$filename}#{$retina-suffix}.#{$extension}");
20 | }
21 | }
22 |
23 | background-size: $background-size;
24 | }
25 | }
26 |
--------------------------------------------------------------------------------
/src/sass/bourbon/addons/_size.scss:
--------------------------------------------------------------------------------
1 | @charset "UTF-8";
2 |
3 | /// Sets the `width` and `height` of the element.
4 | ///
5 | /// @param {List} $size
6 | /// A list of at most 2 size values.
7 | ///
8 | /// If there is only a single value in `$size` it is used for both width and height. All units are supported.
9 | ///
10 | /// @example scss - Usage
11 | /// .first-element {
12 | /// @include size(2em);
13 | /// }
14 | ///
15 | /// .second-element {
16 | /// @include size(auto 10em);
17 | /// }
18 | ///
19 | /// @example css - CSS Output
20 | /// .first-element {
21 | /// width: 2em;
22 | /// height: 2em;
23 | /// }
24 | ///
25 | /// .second-element {
26 | /// width: auto;
27 | /// height: 10em;
28 | /// }
29 | ///
30 | /// @todo Refactor in 5.0.0 to use a comma-separated argument
31 |
32 | @mixin size($value) {
33 | $width: nth($value, 1);
34 | $height: $width;
35 |
36 | @if length($value) > 1 {
37 | $height: nth($value, 2);
38 | }
39 |
40 | @if is-size($height) {
41 | height: $height;
42 | } @else {
43 | @warn "`#{$height}` is not a valid length for the `$height` parameter in the `size` mixin.";
44 | }
45 |
46 | @if is-size($width) {
47 | width: $width;
48 | } @else {
49 | @warn "`#{$width}` is not a valid length for the `$width` parameter in the `size` mixin.";
50 | }
51 | }
52 |
--------------------------------------------------------------------------------
/src/sass/bourbon/addons/_text-inputs.scss:
--------------------------------------------------------------------------------
1 | @charset "UTF-8";
2 |
3 | /// Generates variables for all text-based inputs. Please note that you must use interpolation on the variable: `#{$all-text-inputs}`.
4 | ///
5 | /// @example scss - Usage
6 | /// #{$all-text-inputs} {
7 | /// border: 1px solid #f00;
8 | /// }
9 | ///
10 | /// #{$all-text-inputs-focus},
11 | /// #{$all-text-inputs-hover} {
12 | /// border: 1px solid #0f0;
13 | /// }
14 | ///
15 | /// #{$all-text-inputs-active} {
16 | /// border: 1px solid #00f;
17 | /// }
18 | ///
19 | /// @example css - CSS Output
20 | /// input[type="color"],
21 | /// input[type="date"],
22 | /// input[type="datetime"],
23 | /// input[type="datetime-local"],
24 | /// input[type="email"],
25 | /// input[type="month"],
26 | /// input[type="number"],
27 | /// input[type="password"],
28 | /// input[type="search"],
29 | /// input[type="tel"],
30 | /// input[type="text"],
31 | /// input[type="time"],
32 | /// input[type="url"],
33 | /// input[type="week"],
34 | /// textarea {
35 | /// border: 1px solid #f00;
36 | /// }
37 | ///
38 | /// input[type="color"]:focus,
39 | /// input[type="date"]:focus,
40 | /// input[type="datetime"]:focus,
41 | /// input[type="datetime-local"]:focus,
42 | /// input[type="email"]:focus,
43 | /// input[type="month"]:focus,
44 | /// input[type="number"]:focus,
45 | /// input[type="password"]:focus,
46 | /// input[type="search"]:focus,
47 | /// input[type="tel"]:focus,
48 | /// input[type="text"]:focus,
49 | /// input[type="time"]:focus,
50 | /// input[type="url"]:focus,
51 | /// input[type="week"]:focus,
52 | /// textarea:focus,
53 | /// input[type="color"]:hover,
54 | /// input[type="date"]:hover,
55 | /// input[type="datetime"]:hover,
56 | /// input[type="datetime-local"]:hover,
57 | /// input[type="email"]:hover,
58 | /// input[type="month"]:hover,
59 | /// input[type="number"]:hover,
60 | /// input[type="password"]:hover,
61 | /// input[type="search"]:hover,
62 | /// input[type="tel"]:hover,
63 | /// input[type="text"]:hover,
64 | /// input[type="time"]:hover,
65 | /// input[type="url"]:hover,
66 | /// input[type="week"]:hover,
67 | /// textarea:hover {
68 | /// border: 1px solid #0f0;
69 | /// }
70 | ///
71 | /// input[type="color"]:active,
72 | /// input[type="date"]:active,
73 | /// input[type="datetime"]:active,
74 | /// input[type="datetime-local"]:active,
75 | /// input[type="email"]:active,
76 | /// input[type="month"]:active,
77 | /// input[type="number"]:active,
78 | /// input[type="password"]:active,
79 | /// input[type="search"]:active,
80 | /// input[type="tel"]:active,
81 | /// input[type="text"]:active,
82 | /// input[type="time"]:active,
83 | /// input[type="url"]:active,
84 | /// input[type="week"]:active,
85 | /// textarea:active {
86 | /// border: 1px solid #00f;
87 | /// }
88 | ///
89 | /// @require assign-inputs
90 | ///
91 | /// @type List
92 |
93 | $text-inputs-list: 'input[type="color"]',
94 | 'input[type="date"]',
95 | 'input[type="datetime"]',
96 | 'input[type="datetime-local"]',
97 | 'input[type="email"]',
98 | 'input[type="month"]',
99 | 'input[type="number"]',
100 | 'input[type="password"]',
101 | 'input[type="search"]',
102 | 'input[type="tel"]',
103 | 'input[type="text"]',
104 | 'input[type="time"]',
105 | 'input[type="url"]',
106 | 'input[type="week"]',
107 | 'input:not([type])',
108 | 'textarea';
109 |
110 | $all-text-inputs: assign-inputs($text-inputs-list);
111 | $all-text-inputs-active: assign-inputs($text-inputs-list, active);
112 | $all-text-inputs-focus: assign-inputs($text-inputs-list, focus);
113 | $all-text-inputs-hover: assign-inputs($text-inputs-list, hover);
114 |
--------------------------------------------------------------------------------
/src/sass/bourbon/addons/_timing-functions.scss:
--------------------------------------------------------------------------------
1 | @charset "UTF-8";
2 |
3 | /// CSS cubic-bezier timing functions. Timing functions courtesy of jquery.easie (github.com/jaukia/easie)
4 | ///
5 | /// Timing functions are the same as demoed here: http://jqueryui.com/resources/demos/effect/easing.html
6 | ///
7 | /// @type cubic-bezier
8 |
9 | $ease-in-quad: cubic-bezier(0.550, 0.085, 0.680, 0.530);
10 | $ease-in-cubic: cubic-bezier(0.550, 0.055, 0.675, 0.190);
11 | $ease-in-quart: cubic-bezier(0.895, 0.030, 0.685, 0.220);
12 | $ease-in-quint: cubic-bezier(0.755, 0.050, 0.855, 0.060);
13 | $ease-in-sine: cubic-bezier(0.470, 0.000, 0.745, 0.715);
14 | $ease-in-expo: cubic-bezier(0.950, 0.050, 0.795, 0.035);
15 | $ease-in-circ: cubic-bezier(0.600, 0.040, 0.980, 0.335);
16 | $ease-in-back: cubic-bezier(0.600, -0.280, 0.735, 0.045);
17 |
18 | $ease-out-quad: cubic-bezier(0.250, 0.460, 0.450, 0.940);
19 | $ease-out-cubic: cubic-bezier(0.215, 0.610, 0.355, 1.000);
20 | $ease-out-quart: cubic-bezier(0.165, 0.840, 0.440, 1.000);
21 | $ease-out-quint: cubic-bezier(0.230, 1.000, 0.320, 1.000);
22 | $ease-out-sine: cubic-bezier(0.390, 0.575, 0.565, 1.000);
23 | $ease-out-expo: cubic-bezier(0.190, 1.000, 0.220, 1.000);
24 | $ease-out-circ: cubic-bezier(0.075, 0.820, 0.165, 1.000);
25 | $ease-out-back: cubic-bezier(0.175, 0.885, 0.320, 1.275);
26 |
27 | $ease-in-out-quad: cubic-bezier(0.455, 0.030, 0.515, 0.955);
28 | $ease-in-out-cubic: cubic-bezier(0.645, 0.045, 0.355, 1.000);
29 | $ease-in-out-quart: cubic-bezier(0.770, 0.000, 0.175, 1.000);
30 | $ease-in-out-quint: cubic-bezier(0.860, 0.000, 0.070, 1.000);
31 | $ease-in-out-sine: cubic-bezier(0.445, 0.050, 0.550, 0.950);
32 | $ease-in-out-expo: cubic-bezier(1.000, 0.000, 0.000, 1.000);
33 | $ease-in-out-circ: cubic-bezier(0.785, 0.135, 0.150, 0.860);
34 | $ease-in-out-back: cubic-bezier(0.680, -0.550, 0.265, 1.550);
35 |
--------------------------------------------------------------------------------
/src/sass/bourbon/addons/_triangle.scss:
--------------------------------------------------------------------------------
1 | @mixin triangle($size, $color, $direction) {
2 | $width: nth($size, 1);
3 | $height: nth($size, length($size));
4 | $foreground-color: nth($color, 1);
5 | $background-color: if(length($color) == 2, nth($color, 2), transparent);
6 | height: 0;
7 | width: 0;
8 |
9 | @if ($direction == up) or ($direction == down) or ($direction == right) or ($direction == left) {
10 | $width: $width / 2;
11 | $height: if(length($size) > 1, $height, $height/2);
12 |
13 | @if $direction == up {
14 | border-bottom: $height solid $foreground-color;
15 | border-left: $width solid $background-color;
16 | border-right: $width solid $background-color;
17 | } @else if $direction == right {
18 | border-bottom: $width solid $background-color;
19 | border-left: $height solid $foreground-color;
20 | border-top: $width solid $background-color;
21 | } @else if $direction == down {
22 | border-left: $width solid $background-color;
23 | border-right: $width solid $background-color;
24 | border-top: $height solid $foreground-color;
25 | } @else if $direction == left {
26 | border-bottom: $width solid $background-color;
27 | border-right: $height solid $foreground-color;
28 | border-top: $width solid $background-color;
29 | }
30 | } @else if ($direction == up-right) or ($direction == up-left) {
31 | border-top: $height solid $foreground-color;
32 |
33 | @if $direction == up-right {
34 | border-left: $width solid $background-color;
35 | } @else if $direction == up-left {
36 | border-right: $width solid $background-color;
37 | }
38 | } @else if ($direction == down-right) or ($direction == down-left) {
39 | border-bottom: $height solid $foreground-color;
40 |
41 | @if $direction == down-right {
42 | border-left: $width solid $background-color;
43 | } @else if $direction == down-left {
44 | border-right: $width solid $background-color;
45 | }
46 | } @else if ($direction == inset-up) {
47 | border-color: $background-color $background-color $foreground-color;
48 | border-style: solid;
49 | border-width: $height $width;
50 | } @else if ($direction == inset-down) {
51 | border-color: $foreground-color $background-color $background-color;
52 | border-style: solid;
53 | border-width: $height $width;
54 | } @else if ($direction == inset-right) {
55 | border-color: $background-color $background-color $background-color $foreground-color;
56 | border-style: solid;
57 | border-width: $width $height;
58 | } @else if ($direction == inset-left) {
59 | border-color: $background-color $foreground-color $background-color $background-color;
60 | border-style: solid;
61 | border-width: $width $height;
62 | }
63 | }
64 |
--------------------------------------------------------------------------------
/src/sass/bourbon/addons/_word-wrap.scss:
--------------------------------------------------------------------------------
1 | @charset "UTF-8";
2 |
3 | /// Provides an easy way to change the `word-wrap` property.
4 | ///
5 | /// @param {String} $wrap [break-word]
6 | /// Value for the `word-break` property.
7 | ///
8 | /// @example scss - Usage
9 | /// .wrapper {
10 | /// @include word-wrap(break-word);
11 | /// }
12 | ///
13 | /// @example css - CSS Output
14 | /// .wrapper {
15 | /// overflow-wrap: break-word;
16 | /// word-break: break-all;
17 | /// word-wrap: break-word;
18 | /// }
19 |
20 | @mixin word-wrap($wrap: break-word) {
21 | overflow-wrap: $wrap;
22 | word-wrap: $wrap;
23 |
24 | @if $wrap == break-word {
25 | word-break: break-all;
26 | } @else {
27 | word-break: $wrap;
28 | }
29 | }
30 |
--------------------------------------------------------------------------------
/src/sass/bourbon/css3/_animation.scss:
--------------------------------------------------------------------------------
1 | // http://www.w3.org/TR/css3-animations/#the-animation-name-property-
2 | // Each of these mixins support comma separated lists of values, which allows different transitions for individual properties to be described in a single style rule. Each value in the list corresponds to the value at that same position in the other properties.
3 |
4 | @mixin animation($animations...) {
5 | @include prefixer(animation, $animations, webkit moz spec);
6 | }
7 |
8 | @mixin animation-name($names...) {
9 | @include prefixer(animation-name, $names, webkit moz spec);
10 | }
11 |
12 | @mixin animation-duration($times...) {
13 | @include prefixer(animation-duration, $times, webkit moz spec);
14 | }
15 |
16 | @mixin animation-timing-function($motions...) {
17 | // ease | linear | ease-in | ease-out | ease-in-out
18 | @include prefixer(animation-timing-function, $motions, webkit moz spec);
19 | }
20 |
21 | @mixin animation-iteration-count($values...) {
22 | // infinite |
23 | @include prefixer(animation-iteration-count, $values, webkit moz spec);
24 | }
25 |
26 | @mixin animation-direction($directions...) {
27 | // normal | alternate
28 | @include prefixer(animation-direction, $directions, webkit moz spec);
29 | }
30 |
31 | @mixin animation-play-state($states...) {
32 | // running | paused
33 | @include prefixer(animation-play-state, $states, webkit moz spec);
34 | }
35 |
36 | @mixin animation-delay($times...) {
37 | @include prefixer(animation-delay, $times, webkit moz spec);
38 | }
39 |
40 | @mixin animation-fill-mode($modes...) {
41 | // none | forwards | backwards | both
42 | @include prefixer(animation-fill-mode, $modes, webkit moz spec);
43 | }
44 |
--------------------------------------------------------------------------------
/src/sass/bourbon/css3/_appearance.scss:
--------------------------------------------------------------------------------
1 | @mixin appearance($value) {
2 | @include prefixer(appearance, $value, webkit moz ms o spec);
3 | }
4 |
--------------------------------------------------------------------------------
/src/sass/bourbon/css3/_backface-visibility.scss:
--------------------------------------------------------------------------------
1 | @mixin backface-visibility($visibility) {
2 | @include prefixer(backface-visibility, $visibility, webkit spec);
3 | }
4 |
--------------------------------------------------------------------------------
/src/sass/bourbon/css3/_background-image.scss:
--------------------------------------------------------------------------------
1 | //************************************************************************//
2 | // Background-image property for adding multiple background images with
3 | // gradients, or for stringing multiple gradients together.
4 | //************************************************************************//
5 |
6 | @mixin background-image($images...) {
7 | $webkit-images: ();
8 | $spec-images: ();
9 |
10 | @each $image in $images {
11 | $webkit-image: ();
12 | $spec-image: ();
13 |
14 | @if (type-of($image) == string) {
15 | $url-str: str-slice($image, 1, 3);
16 | $gradient-type: str-slice($image, 1, 6);
17 |
18 | @if $url-str == "url" {
19 | $webkit-image: $image;
20 | $spec-image: $image;
21 | }
22 |
23 | @else if $gradient-type == "linear" {
24 | $gradients: _linear-gradient-parser($image);
25 | $webkit-image: map-get($gradients, webkit-image);
26 | $spec-image: map-get($gradients, spec-image);
27 | }
28 |
29 | @else if $gradient-type == "radial" {
30 | $gradients: _radial-gradient-parser($image);
31 | $webkit-image: map-get($gradients, webkit-image);
32 | $spec-image: map-get($gradients, spec-image);
33 | }
34 | }
35 |
36 | $webkit-images: append($webkit-images, $webkit-image, comma);
37 | $spec-images: append($spec-images, $spec-image, comma);
38 | }
39 |
40 | background-image: $webkit-images;
41 | background-image: $spec-images;
42 | }
43 |
--------------------------------------------------------------------------------
/src/sass/bourbon/css3/_background.scss:
--------------------------------------------------------------------------------
1 | //************************************************************************//
2 | // Background property for adding multiple backgrounds using shorthand
3 | // notation.
4 | //************************************************************************//
5 |
6 | @mixin background($backgrounds...) {
7 | $webkit-backgrounds: ();
8 | $spec-backgrounds: ();
9 |
10 | @each $background in $backgrounds {
11 | $webkit-background: ();
12 | $spec-background: ();
13 | $background-type: type-of($background);
14 |
15 | @if $background-type == string or $background-type == list {
16 | $background-str: if($background-type == list, nth($background, 1), $background);
17 |
18 | $url-str: str-slice($background-str, 1, 3);
19 | $gradient-type: str-slice($background-str, 1, 6);
20 |
21 | @if $url-str == "url" {
22 | $webkit-background: $background;
23 | $spec-background: $background;
24 | }
25 |
26 | @else if $gradient-type == "linear" {
27 | $gradients: _linear-gradient-parser("#{$background}");
28 | $webkit-background: map-get($gradients, webkit-image);
29 | $spec-background: map-get($gradients, spec-image);
30 | }
31 |
32 | @else if $gradient-type == "radial" {
33 | $gradients: _radial-gradient-parser("#{$background}");
34 | $webkit-background: map-get($gradients, webkit-image);
35 | $spec-background: map-get($gradients, spec-image);
36 | }
37 |
38 | @else {
39 | $webkit-background: $background;
40 | $spec-background: $background;
41 | }
42 | }
43 |
44 | @else {
45 | $webkit-background: $background;
46 | $spec-background: $background;
47 | }
48 |
49 | $webkit-backgrounds: append($webkit-backgrounds, $webkit-background, comma);
50 | $spec-backgrounds: append($spec-backgrounds, $spec-background, comma);
51 | }
52 |
53 | background: $webkit-backgrounds;
54 | background: $spec-backgrounds;
55 | }
56 |
--------------------------------------------------------------------------------
/src/sass/bourbon/css3/_border-image.scss:
--------------------------------------------------------------------------------
1 | @mixin border-image($borders...) {
2 | $webkit-borders: ();
3 | $spec-borders: ();
4 |
5 | @each $border in $borders {
6 | $webkit-border: ();
7 | $spec-border: ();
8 | $border-type: type-of($border);
9 |
10 | @if $border-type == string or list {
11 | $border-str: if($border-type == list, nth($border, 1), $border);
12 |
13 | $url-str: str-slice($border-str, 1, 3);
14 | $gradient-type: str-slice($border-str, 1, 6);
15 |
16 | @if $url-str == "url" {
17 | $webkit-border: $border;
18 | $spec-border: $border;
19 | }
20 |
21 | @else if $gradient-type == "linear" {
22 | $gradients: _linear-gradient-parser("#{$border}");
23 | $webkit-border: map-get($gradients, webkit-image);
24 | $spec-border: map-get($gradients, spec-image);
25 | }
26 |
27 | @else if $gradient-type == "radial" {
28 | $gradients: _radial-gradient-parser("#{$border}");
29 | $webkit-border: map-get($gradients, webkit-image);
30 | $spec-border: map-get($gradients, spec-image);
31 | }
32 |
33 | @else {
34 | $webkit-border: $border;
35 | $spec-border: $border;
36 | }
37 | }
38 |
39 | @else {
40 | $webkit-border: $border;
41 | $spec-border: $border;
42 | }
43 |
44 | $webkit-borders: append($webkit-borders, $webkit-border, comma);
45 | $spec-borders: append($spec-borders, $spec-border, comma);
46 | }
47 |
48 | -webkit-border-image: $webkit-borders;
49 | border-image: $spec-borders;
50 | border-style: solid;
51 | }
52 |
53 | //Examples:
54 | // @include border-image(url("image.png"));
55 | // @include border-image(url("image.png") 20 stretch);
56 | // @include border-image(linear-gradient(45deg, orange, yellow));
57 | // @include border-image(linear-gradient(45deg, orange, yellow) stretch);
58 | // @include border-image(linear-gradient(45deg, orange, yellow) 20 30 40 50 stretch round);
59 | // @include border-image(radial-gradient(top, cover, orange, yellow, orange));
60 |
--------------------------------------------------------------------------------
/src/sass/bourbon/css3/_calc.scss:
--------------------------------------------------------------------------------
1 | @mixin calc($property, $value) {
2 | #{$property}: -webkit-calc(#{$value});
3 | #{$property}: calc(#{$value});
4 | }
5 |
--------------------------------------------------------------------------------
/src/sass/bourbon/css3/_columns.scss:
--------------------------------------------------------------------------------
1 | @mixin columns($arg: auto) {
2 | // ||
3 | @include prefixer(columns, $arg, webkit moz spec);
4 | }
5 |
6 | @mixin column-count($int: auto) {
7 | // auto || integer
8 | @include prefixer(column-count, $int, webkit moz spec);
9 | }
10 |
11 | @mixin column-gap($length: normal) {
12 | // normal || length
13 | @include prefixer(column-gap, $length, webkit moz spec);
14 | }
15 |
16 | @mixin column-fill($arg: auto) {
17 | // auto || length
18 | @include prefixer(column-fill, $arg, webkit moz spec);
19 | }
20 |
21 | @mixin column-rule($arg) {
22 | // || ||
23 | @include prefixer(column-rule, $arg, webkit moz spec);
24 | }
25 |
26 | @mixin column-rule-color($color) {
27 | @include prefixer(column-rule-color, $color, webkit moz spec);
28 | }
29 |
30 | @mixin column-rule-style($style: none) {
31 | // none | hidden | dashed | dotted | double | groove | inset | inset | outset | ridge | solid
32 | @include prefixer(column-rule-style, $style, webkit moz spec);
33 | }
34 |
35 | @mixin column-rule-width ($width: none) {
36 | @include prefixer(column-rule-width, $width, webkit moz spec);
37 | }
38 |
39 | @mixin column-span($arg: none) {
40 | // none || all
41 | @include prefixer(column-span, $arg, webkit moz spec);
42 | }
43 |
44 | @mixin column-width($length: auto) {
45 | // auto || length
46 | @include prefixer(column-width, $length, webkit moz spec);
47 | }
48 |
--------------------------------------------------------------------------------
/src/sass/bourbon/css3/_filter.scss:
--------------------------------------------------------------------------------
1 | @mixin filter($function: none) {
2 | // [
3 | @include prefixer(perspective, $depth, webkit moz spec);
4 | }
5 |
6 | @mixin perspective-origin($value: 50% 50%) {
7 | @include prefixer(perspective-origin, $value, webkit moz spec);
8 | }
9 |
--------------------------------------------------------------------------------
/src/sass/bourbon/css3/_placeholder.scss:
--------------------------------------------------------------------------------
1 | @mixin placeholder {
2 | $placeholders: ":-webkit-input" ":-moz" "-moz" "-ms-input";
3 | @each $placeholder in $placeholders {
4 | &:#{$placeholder}-placeholder {
5 | @content;
6 | }
7 | }
8 | }
9 |
--------------------------------------------------------------------------------
/src/sass/bourbon/css3/_radial-gradient.scss:
--------------------------------------------------------------------------------
1 | // Requires Sass 3.1+
2 | @mixin radial-gradient($g1, $g2,
3 | $g3: null, $g4: null,
4 | $g5: null, $g6: null,
5 | $g7: null, $g8: null,
6 | $g9: null, $g10: null,
7 | $pos: null,
8 | $shape-size: null,
9 | $fallback: null) {
10 |
11 | $data: _radial-arg-parser($g1, $g2, $pos, $shape-size);
12 | $g1: nth($data, 1);
13 | $g2: nth($data, 2);
14 | $pos: nth($data, 3);
15 | $shape-size: nth($data, 4);
16 |
17 | $full: $g1, $g2, $g3, $g4, $g5, $g6, $g7, $g8, $g9, $g10;
18 |
19 | // Strip deprecated cover/contain for spec
20 | $shape-size-spec: _shape-size-stripper($shape-size);
21 |
22 | // Set $g1 as the default fallback color
23 | $first-color: nth($full, 1);
24 | $fallback-color: nth($first-color, 1);
25 |
26 | @if (type-of($fallback) == color) or ($fallback == "transparent") {
27 | $fallback-color: $fallback;
28 | }
29 |
30 | // Add Commas and spaces
31 | $shape-size: if($shape-size, "#{$shape-size}, ", null);
32 | $pos: if($pos, "#{$pos}, ", null);
33 | $pos-spec: if($pos, "at #{$pos}", null);
34 | $shape-size-spec: if(($shape-size-spec != " ") and ($pos == null), "#{$shape-size-spec}, ", "#{$shape-size-spec} ");
35 |
36 | background-color: $fallback-color;
37 | background-image: -webkit-radial-gradient(unquote(#{$pos}#{$shape-size}#{$full}));
38 | background-image: unquote("radial-gradient(#{$shape-size-spec}#{$pos-spec}#{$full})");
39 | }
40 |
--------------------------------------------------------------------------------
/src/sass/bourbon/css3/_selection.scss:
--------------------------------------------------------------------------------
1 | @charset "UTF-8";
2 |
3 | /// Outputs the spec and prefixed versions of the `::selection` pseudo-element.
4 | ///
5 | /// @param {Bool} $current-selector [false]
6 | /// If set to `true`, it takes the current element into consideration.
7 | ///
8 | /// @example scss - Usage
9 | /// .element {
10 | /// @include selection(true) {
11 | /// background-color: #ffbb52;
12 | /// }
13 | /// }
14 | ///
15 | /// @example css - CSS Output
16 | /// .element::-moz-selection {
17 | /// background-color: #ffbb52;
18 | /// }
19 | ///
20 | /// .element::selection {
21 | /// background-color: #ffbb52;
22 | /// }
23 |
24 | @mixin selection($current-selector: false) {
25 | @if $current-selector {
26 | &::-moz-selection {
27 | @content;
28 | }
29 |
30 | &::selection {
31 | @content;
32 | }
33 | } @else {
34 | ::-moz-selection {
35 | @content;
36 | }
37 |
38 | ::selection {
39 | @content;
40 | }
41 | }
42 | }
43 |
--------------------------------------------------------------------------------
/src/sass/bourbon/css3/_text-decoration.scss:
--------------------------------------------------------------------------------
1 | @mixin text-decoration($value) {
2 | // || ||
3 | @include prefixer(text-decoration, $value, moz);
4 | }
5 |
6 | @mixin text-decoration-line($line: none) {
7 | // none || underline || overline || line-through
8 | @include prefixer(text-decoration-line, $line, moz);
9 | }
10 |
11 | @mixin text-decoration-style($style: solid) {
12 | // solid || double || dotted || dashed || wavy
13 | @include prefixer(text-decoration-style, $style, moz webkit);
14 | }
15 |
16 | @mixin text-decoration-color($color: currentColor) {
17 | // currentColor ||
18 | @include prefixer(text-decoration-color, $color, moz);
19 | }
20 |
--------------------------------------------------------------------------------
/src/sass/bourbon/css3/_transform.scss:
--------------------------------------------------------------------------------
1 | @mixin transform($property: none) {
2 | // none |
3 | @include prefixer(transform, $property, webkit moz ms o spec);
4 | }
5 |
6 | @mixin transform-origin($axes: 50%) {
7 | // x-axis - left | center | right | length | %
8 | // y-axis - top | center | bottom | length | %
9 | // z-axis - length
10 | @include prefixer(transform-origin, $axes, webkit moz ms o spec);
11 | }
12 |
13 | @mixin transform-style($style: flat) {
14 | @include prefixer(transform-style, $style, webkit moz ms o spec);
15 | }
16 |
--------------------------------------------------------------------------------
/src/sass/bourbon/css3/_transition.scss:
--------------------------------------------------------------------------------
1 | // Shorthand mixin. Supports multiple parentheses-deliminated values for each variable.
2 | // Example: @include transition (all 2s ease-in-out);
3 | // @include transition (opacity 1s ease-in 2s, width 2s ease-out);
4 | // @include transition-property (transform, opacity);
5 |
6 | @mixin transition($properties...) {
7 | // Fix for vendor-prefix transform property
8 | $needs-prefixes: false;
9 | $webkit: ();
10 | $moz: ();
11 | $spec: ();
12 |
13 | // Create lists for vendor-prefixed transform
14 | @each $list in $properties {
15 | @if nth($list, 1) == "transform" {
16 | $needs-prefixes: true;
17 | $list1: -webkit-transform;
18 | $list2: -moz-transform;
19 | $list3: ();
20 |
21 | @each $var in $list {
22 | $list3: join($list3, $var);
23 |
24 | @if $var != "transform" {
25 | $list1: join($list1, $var);
26 | $list2: join($list2, $var);
27 | }
28 | }
29 |
30 | $webkit: append($webkit, $list1);
31 | $moz: append($moz, $list2);
32 | $spec: append($spec, $list3);
33 | } @else {
34 | $webkit: append($webkit, $list, comma);
35 | $moz: append($moz, $list, comma);
36 | $spec: append($spec, $list, comma);
37 | }
38 | }
39 |
40 | @if $needs-prefixes {
41 | -webkit-transition: $webkit;
42 | -moz-transition: $moz;
43 | transition: $spec;
44 | } @else {
45 | @if length($properties) >= 1 {
46 | @include prefixer(transition, $properties, webkit moz spec);
47 | } @else {
48 | $properties: all 0.15s ease-out 0s;
49 | @include prefixer(transition, $properties, webkit moz spec);
50 | }
51 | }
52 | }
53 |
54 | @mixin transition-property($properties...) {
55 | -webkit-transition-property: transition-property-names($properties, "webkit");
56 | -moz-transition-property: transition-property-names($properties, "moz");
57 | transition-property: transition-property-names($properties, false);
58 | }
59 |
60 | @mixin transition-duration($times...) {
61 | @include prefixer(transition-duration, $times, webkit moz spec);
62 | }
63 |
64 | @mixin transition-timing-function($motions...) {
65 | // ease | linear | ease-in | ease-out | ease-in-out | cubic-bezier()
66 | @include prefixer(transition-timing-function, $motions, webkit moz spec);
67 | }
68 |
69 | @mixin transition-delay($times...) {
70 | @include prefixer(transition-delay, $times, webkit moz spec);
71 | }
72 |
--------------------------------------------------------------------------------
/src/sass/bourbon/css3/_user-select.scss:
--------------------------------------------------------------------------------
1 | @mixin user-select($value: none) {
2 | @include prefixer(user-select, $value, webkit moz ms spec);
3 | }
4 |
--------------------------------------------------------------------------------
/src/sass/bourbon/functions/_assign-inputs.scss:
--------------------------------------------------------------------------------
1 | @function assign-inputs($inputs, $pseudo: null) {
2 | $list: ();
3 |
4 | @each $input in $inputs {
5 | $input: unquote($input);
6 | $input: if($pseudo, $input + ":" + $pseudo, $input);
7 | $list: append($list, $input, comma);
8 | }
9 |
10 | @return $list;
11 | }
12 |
--------------------------------------------------------------------------------
/src/sass/bourbon/functions/_contains-falsy.scss:
--------------------------------------------------------------------------------
1 | @charset "UTF-8";
2 |
3 | /// Checks if a list does not contains a value.
4 | ///
5 | /// @access private
6 | ///
7 | /// @param {List} $list
8 | /// The list to check against.
9 | ///
10 | /// @return {Bool}
11 |
12 | @function contains-falsy($list) {
13 | @each $item in $list {
14 | @if not $item {
15 | @return true;
16 | }
17 | }
18 |
19 | @return false;
20 | }
21 |
--------------------------------------------------------------------------------
/src/sass/bourbon/functions/_contains.scss:
--------------------------------------------------------------------------------
1 | @charset "UTF-8";
2 |
3 | /// Checks if a list contains a value(s).
4 | ///
5 | /// @access private
6 | ///
7 | /// @param {List} $list
8 | /// The list to check against.
9 | ///
10 | /// @param {List} $values
11 | /// A single value or list of values to check for.
12 | ///
13 | /// @example scss - Usage
14 | /// contains($list, $value)
15 | ///
16 | /// @return {Bool}
17 |
18 | @function contains($list, $values...) {
19 | @each $value in $values {
20 | @if type-of(index($list, $value)) != "number" {
21 | @return false;
22 | }
23 | }
24 |
25 | @return true;
26 | }
27 |
--------------------------------------------------------------------------------
/src/sass/bourbon/functions/_is-length.scss:
--------------------------------------------------------------------------------
1 | @charset "UTF-8";
2 |
3 | /// Checks for a valid CSS length.
4 | ///
5 | /// @param {String} $value
6 |
7 | @function is-length($value) {
8 | @return type-of($value) != "null" and (str-slice($value + "", 1, 4) == "calc"
9 | or index(auto inherit initial 0, $value)
10 | or (type-of($value) == "number" and not(unitless($value))));
11 | }
12 |
--------------------------------------------------------------------------------
/src/sass/bourbon/functions/_is-light.scss:
--------------------------------------------------------------------------------
1 | @charset "UTF-8";
2 |
3 | /// Programatically determines whether a color is light or dark.
4 | ///
5 | /// @link http://robots.thoughtbot.com/closer-look-color-lightness
6 | ///
7 | /// @param {Color (Hex)} $color
8 | ///
9 | /// @example scss - Usage
10 | /// is-light($color)
11 | ///
12 | /// @return {Bool}
13 |
14 | @function is-light($hex-color) {
15 | $-local-red: red(rgba($hex-color, 1));
16 | $-local-green: green(rgba($hex-color, 1));
17 | $-local-blue: blue(rgba($hex-color, 1));
18 | $-local-lightness: ($-local-red * 0.2126 + $-local-green * 0.7152 + $-local-blue * 0.0722) / 255;
19 |
20 | @return $-local-lightness > 0.6;
21 | }
22 |
--------------------------------------------------------------------------------
/src/sass/bourbon/functions/_is-number.scss:
--------------------------------------------------------------------------------
1 | @charset "UTF-8";
2 |
3 | /// Checks for a valid number.
4 | ///
5 | /// @param {Number} $value
6 | ///
7 | /// @require {function} contains
8 |
9 | @function is-number($value) {
10 | @return contains("0" "1" "2" "3" "4" "5" "6" "7" "8" "9" 0 1 2 3 4 5 6 7 8 9, $value);
11 | }
12 |
--------------------------------------------------------------------------------
/src/sass/bourbon/functions/_is-size.scss:
--------------------------------------------------------------------------------
1 | @charset "UTF-8";
2 |
3 | /// Checks for a valid CSS size.
4 | ///
5 | /// @param {String} $value
6 | ///
7 | /// @require {function} contains
8 | /// @require {function} is-length
9 |
10 | @function is-size($value) {
11 | @return is-length($value)
12 | or contains("fill" "fit-content" "min-content" "max-content", $value);
13 | }
14 |
--------------------------------------------------------------------------------
/src/sass/bourbon/functions/_modular-scale.scss:
--------------------------------------------------------------------------------
1 | // Scaling Variables
2 | $golden: 1.618;
3 | $minor-second: 1.067;
4 | $major-second: 1.125;
5 | $minor-third: 1.2;
6 | $major-third: 1.25;
7 | $perfect-fourth: 1.333;
8 | $augmented-fourth: 1.414;
9 | $perfect-fifth: 1.5;
10 | $minor-sixth: 1.6;
11 | $major-sixth: 1.667;
12 | $minor-seventh: 1.778;
13 | $major-seventh: 1.875;
14 | $octave: 2;
15 | $major-tenth: 2.5;
16 | $major-eleventh: 2.667;
17 | $major-twelfth: 3;
18 | $double-octave: 4;
19 |
20 | $modular-scale-ratio: $perfect-fourth !default;
21 | $modular-scale-base: em($em-base) !default;
22 |
23 | @function modular-scale($increment, $value: $modular-scale-base, $ratio: $modular-scale-ratio) {
24 | $v1: nth($value, 1);
25 | $v2: nth($value, length($value));
26 | $value: $v1;
27 |
28 | // scale $v2 to just above $v1
29 | @while $v2 > $v1 {
30 | $v2: ($v2 / $ratio); // will be off-by-1
31 | }
32 | @while $v2 < $v1 {
33 | $v2: ($v2 * $ratio); // will fix off-by-1
34 | }
35 |
36 | // check AFTER scaling $v2 to prevent double-counting corner-case
37 | $double-stranded: $v2 > $v1;
38 |
39 | @if $increment > 0 {
40 | @for $i from 1 through $increment {
41 | @if $double-stranded and ($v1 * $ratio) > $v2 {
42 | $value: $v2;
43 | $v2: ($v2 * $ratio);
44 | } @else {
45 | $v1: ($v1 * $ratio);
46 | $value: $v1;
47 | }
48 | }
49 | }
50 |
51 | @if $increment < 0 {
52 | // adjust $v2 to just below $v1
53 | @if $double-stranded {
54 | $v2: ($v2 / $ratio);
55 | }
56 |
57 | @for $i from $increment through -1 {
58 | @if $double-stranded and ($v1 / $ratio) < $v2 {
59 | $value: $v2;
60 | $v2: ($v2 / $ratio);
61 | } @else {
62 | $v1: ($v1 / $ratio);
63 | $value: $v1;
64 | }
65 | }
66 | }
67 |
68 | @return $value;
69 | }
70 |
--------------------------------------------------------------------------------
/src/sass/bourbon/functions/_px-to-em.scss:
--------------------------------------------------------------------------------
1 | // Convert pixels to ems
2 | // eg. for a relational value of 12px write em(12) when the parent is 16px
3 | // if the parent is another value say 24px write em(12, 24)
4 |
5 | @function em($pxval, $base: $em-base) {
6 | @if not unitless($pxval) {
7 | $pxval: strip-units($pxval);
8 | }
9 | @if not unitless($base) {
10 | $base: strip-units($base);
11 | }
12 | @return ($pxval / $base) * 1em;
13 | }
14 |
--------------------------------------------------------------------------------
/src/sass/bourbon/functions/_px-to-rem.scss:
--------------------------------------------------------------------------------
1 | // Convert pixels to rems
2 | // eg. for a relational value of 12px write rem(12)
3 | // Assumes $em-base is the font-size of
4 |
5 | @function rem($pxval) {
6 | @if not unitless($pxval) {
7 | $pxval: strip-units($pxval);
8 | }
9 |
10 | $base: $em-base;
11 | @if not unitless($base) {
12 | $base: strip-units($base);
13 | }
14 | @return ($pxval / $base) * 1rem;
15 | }
16 |
--------------------------------------------------------------------------------
/src/sass/bourbon/functions/_shade.scss:
--------------------------------------------------------------------------------
1 | @charset "UTF-8";
2 |
3 | /// Mixes a color with black.
4 | ///
5 | /// @param {Color} $color
6 | ///
7 | /// @param {Number (Percentage)} $percent
8 | /// The amount of black to be mixed in.
9 | ///
10 | /// @example scss - Usage
11 | /// .element {
12 | /// background-color: shade(#ffbb52, 60%);
13 | /// }
14 | ///
15 | /// @example css - CSS Output
16 | /// .element {
17 | /// background-color: #664a20;
18 | /// }
19 | ///
20 | /// @return {Color}
21 |
22 | @function shade($color, $percent) {
23 | @return mix(#000, $color, $percent);
24 | }
25 |
--------------------------------------------------------------------------------
/src/sass/bourbon/functions/_strip-units.scss:
--------------------------------------------------------------------------------
1 | @charset "UTF-8";
2 |
3 | /// Strips the unit from a number.
4 | ///
5 | /// @param {Number (With Unit)} $value
6 | ///
7 | /// @example scss - Usage
8 | /// $dimension: strip-units(10em);
9 | ///
10 | /// @example css - CSS Output
11 | /// $dimension: 10;
12 | ///
13 | /// @return {Number (Unitless)}
14 |
15 | @function strip-units($value) {
16 | @return ($value / ($value * 0 + 1));
17 | }
18 |
--------------------------------------------------------------------------------
/src/sass/bourbon/functions/_tint.scss:
--------------------------------------------------------------------------------
1 | @charset "UTF-8";
2 |
3 | /// Mixes a color with white.
4 | ///
5 | /// @param {Color} $color
6 | ///
7 | /// @param {Number (Percentage)} $percent
8 | /// The amount of white to be mixed in.
9 | ///
10 | /// @example scss - Usage
11 | /// .element {
12 | /// background-color: tint(#6ecaa6, 40%);
13 | /// }
14 | ///
15 | /// @example css - CSS Output
16 | /// .element {
17 | /// background-color: #a8dfc9;
18 | /// }
19 | ///
20 | /// @return {Color}
21 |
22 | @function tint($color, $percent) {
23 | @return mix(#fff, $color, $percent);
24 | }
25 |
--------------------------------------------------------------------------------
/src/sass/bourbon/functions/_transition-property-name.scss:
--------------------------------------------------------------------------------
1 | // Return vendor-prefixed property names if appropriate
2 | // Example: transition-property-names((transform, color, background), moz) -> -moz-transform, color, background
3 | //************************************************************************//
4 | @function transition-property-names($props, $vendor: false) {
5 | $new-props: ();
6 |
7 | @each $prop in $props {
8 | $new-props: append($new-props, transition-property-name($prop, $vendor), comma);
9 | }
10 |
11 | @return $new-props;
12 | }
13 |
14 | @function transition-property-name($prop, $vendor: false) {
15 | // put other properties that need to be prefixed here aswell
16 | @if $vendor and $prop == transform {
17 | @return unquote('-'+$vendor+'-'+$prop);
18 | }
19 | @else {
20 | @return $prop;
21 | }
22 | }
23 |
--------------------------------------------------------------------------------
/src/sass/bourbon/functions/_unpack.scss:
--------------------------------------------------------------------------------
1 | @charset "UTF-8";
2 |
3 | /// Converts shorthand to the 4-value syntax.
4 | ///
5 | /// @param {List} $shorthand
6 | ///
7 | /// @example scss - Usage
8 | /// .element {
9 | /// margin: unpack(1em 2em);
10 | /// }
11 | ///
12 | /// @example css - CSS Output
13 | /// .element {
14 | /// margin: 1em 2em 1em 2em;
15 | /// }
16 |
17 | @function unpack($shorthand) {
18 | @if length($shorthand) == 1 {
19 | @return nth($shorthand, 1) nth($shorthand, 1) nth($shorthand, 1) nth($shorthand, 1);
20 | } @else if length($shorthand) == 2 {
21 | @return nth($shorthand, 1) nth($shorthand, 2) nth($shorthand, 1) nth($shorthand, 2);
22 | } @else if length($shorthand) == 3 {
23 | @return nth($shorthand, 1) nth($shorthand, 2) nth($shorthand, 3) nth($shorthand, 2);
24 | } @else {
25 | @return $shorthand;
26 | }
27 | }
28 |
--------------------------------------------------------------------------------
/src/sass/bourbon/helpers/_convert-units.scss:
--------------------------------------------------------------------------------
1 | //************************************************************************//
2 | // Helper function for str-to-num fn.
3 | // Source: http://sassmeister.com/gist/9647408
4 | //************************************************************************//
5 | @function _convert-units($number, $unit) {
6 | $strings: "px", "cm", "mm", "%", "ch", "pica", "in", "em", "rem", "pt", "pc", "ex", "vw", "vh", "vmin", "vmax", "deg", "rad", "grad", "turn";
7 | $units: 1px, 1cm, 1mm, 1%, 1ch, 1pica, 1in, 1em, 1rem, 1pt, 1pc, 1ex, 1vw, 1vh, 1vmin, 1vmax, 1deg, 1rad, 1grad, 1turn;
8 | $index: index($strings, $unit);
9 |
10 | @if not $index {
11 | @warn "Unknown unit `#{$unit}`.";
12 | @return false;
13 | }
14 |
15 | @if type-of($number) != "number" {
16 | @warn "`#{$number} is not a number`";
17 | @return false;
18 | }
19 |
20 | @return $number * nth($units, $index);
21 | }
22 |
--------------------------------------------------------------------------------
/src/sass/bourbon/helpers/_directional-values.scss:
--------------------------------------------------------------------------------
1 | @charset "UTF-8";
2 |
3 | /// Directional-property mixins are shorthands for writing properties like the following
4 | ///
5 | /// @ignore You can also use `false` instead of `null`.
6 | ///
7 | /// @param {List} $vals
8 | /// List of directional values
9 | ///
10 | /// @example scss - Usage
11 | /// .element {
12 | /// @include border-style(dotted null);
13 | /// @include margin(null 0 10px);
14 | /// }
15 | ///
16 | /// @example css - CSS Output
17 | /// .element {
18 | /// border-bottom-style: dotted;
19 | /// border-top-style: dotted;
20 | /// margin-bottom: 10px;
21 | /// margin-left: 0;
22 | /// margin-right: 0;
23 | /// }
24 | ///
25 | /// @require {function} contains-falsy
26 | ///
27 | /// @return {List}
28 |
29 | @function collapse-directionals($vals) {
30 | $output: null;
31 |
32 | $a: nth($vals, 1);
33 | $b: if(length($vals) < 2, $a, nth($vals, 2));
34 | $c: if(length($vals) < 3, $a, nth($vals, 3));
35 | $d: if(length($vals) < 2, $a, nth($vals, if(length($vals) < 4, 2, 4)));
36 |
37 | @if $a == 0 { $a: 0; }
38 | @if $b == 0 { $b: 0; }
39 | @if $c == 0 { $c: 0; }
40 | @if $d == 0 { $d: 0; }
41 |
42 | @if $a == $b and $a == $c and $a == $d { $output: $a; }
43 | @else if $a == $c and $b == $d { $output: $a $b; }
44 | @else if $b == $d { $output: $a $b $c; }
45 | @else { $output: $a $b $c $d; }
46 |
47 | @return $output;
48 | }
49 |
50 | /// Output directional properties, for instance `margin`.
51 | ///
52 | /// @access private
53 | ///
54 | /// @param {String} $pre
55 | /// Prefix to use
56 | /// @param {String} $suf
57 | /// Suffix to use
58 | /// @param {List} $vals
59 | /// List of values
60 | ///
61 | /// @require {function} collapse-directionals
62 | /// @require {function} contains-falsy
63 |
64 | @mixin directional-property($pre, $suf, $vals) {
65 | // Property Names
66 | $top: $pre + "-top" + if($suf, "-#{$suf}", "");
67 | $bottom: $pre + "-bottom" + if($suf, "-#{$suf}", "");
68 | $left: $pre + "-left" + if($suf, "-#{$suf}", "");
69 | $right: $pre + "-right" + if($suf, "-#{$suf}", "");
70 | $all: $pre + if($suf, "-#{$suf}", "");
71 |
72 | $vals: collapse-directionals($vals);
73 |
74 | @if contains-falsy($vals) {
75 | @if nth($vals, 1) { #{$top}: nth($vals, 1); }
76 |
77 | @if length($vals) == 1 {
78 | @if nth($vals, 1) { #{$right}: nth($vals, 1); }
79 | } @else {
80 | @if nth($vals, 2) { #{$right}: nth($vals, 2); }
81 | }
82 |
83 | @if length($vals) == 2 {
84 | @if nth($vals, 1) { #{$bottom}: nth($vals, 1); }
85 | @if nth($vals, 2) { #{$left}: nth($vals, 2); }
86 | } @else if length($vals) == 3 {
87 | @if nth($vals, 3) { #{$bottom}: nth($vals, 3); }
88 | @if nth($vals, 2) { #{$left}: nth($vals, 2); }
89 | } @else if length($vals) == 4 {
90 | @if nth($vals, 3) { #{$bottom}: nth($vals, 3); }
91 | @if nth($vals, 4) { #{$left}: nth($vals, 4); }
92 | }
93 | } @else {
94 | #{$all}: $vals;
95 | }
96 | }
97 |
--------------------------------------------------------------------------------
/src/sass/bourbon/helpers/_font-source-declaration.scss:
--------------------------------------------------------------------------------
1 | // Used for creating the source string for fonts using @font-face
2 | // Reference: http://goo.gl/Ru1bKP
3 |
4 | @function font-url-prefixer($asset-pipeline) {
5 | @if $asset-pipeline == true {
6 | @return font-url;
7 | } @else {
8 | @return url;
9 | }
10 | }
11 |
12 | @function font-source-declaration(
13 | $font-family,
14 | $file-path,
15 | $asset-pipeline,
16 | $file-formats,
17 | $font-url) {
18 |
19 | $src: ();
20 |
21 | $formats-map: (
22 | eot: "#{$file-path}.eot?#iefix" format("embedded-opentype"),
23 | woff2: "#{$file-path}.woff2" format("woff2"),
24 | woff: "#{$file-path}.woff" format("woff"),
25 | ttf: "#{$file-path}.ttf" format("truetype"),
26 | svg: "#{$file-path}.svg##{$font-family}" format("svg")
27 | );
28 |
29 | @each $key, $values in $formats-map {
30 | @if contains($file-formats, $key) {
31 | $file-path: nth($values, 1);
32 | $font-format: nth($values, 2);
33 |
34 | @if $asset-pipeline == true {
35 | $src: append($src, font-url($file-path) $font-format, comma);
36 | } @else {
37 | $src: append($src, url($file-path) $font-format, comma);
38 | }
39 | }
40 | }
41 |
42 | @return $src;
43 | }
44 |
--------------------------------------------------------------------------------
/src/sass/bourbon/helpers/_gradient-positions-parser.scss:
--------------------------------------------------------------------------------
1 | @function _gradient-positions-parser($gradient-type, $gradient-positions) {
2 | @if $gradient-positions
3 | and ($gradient-type == linear)
4 | and (type-of($gradient-positions) != color) {
5 | $gradient-positions: _linear-positions-parser($gradient-positions);
6 | }
7 | @else if $gradient-positions
8 | and ($gradient-type == radial)
9 | and (type-of($gradient-positions) != color) {
10 | $gradient-positions: _radial-positions-parser($gradient-positions);
11 | }
12 | @return $gradient-positions;
13 | }
14 |
--------------------------------------------------------------------------------
/src/sass/bourbon/helpers/_linear-angle-parser.scss:
--------------------------------------------------------------------------------
1 | // Private function for linear-gradient-parser
2 | @function _linear-angle-parser($image, $first-val, $prefix, $suffix) {
3 | $offset: null;
4 | $unit-short: str-slice($first-val, str-length($first-val) - 2, str-length($first-val));
5 | $unit-long: str-slice($first-val, str-length($first-val) - 3, str-length($first-val));
6 |
7 | @if ($unit-long == "grad") or
8 | ($unit-long == "turn") {
9 | $offset: if($unit-long == "grad", -100grad * 3, -0.75turn);
10 | }
11 |
12 | @else if ($unit-short == "deg") or
13 | ($unit-short == "rad") {
14 | $offset: if($unit-short == "deg", -90 * 3, 1.6rad);
15 | }
16 |
17 | @if $offset {
18 | $num: _str-to-num($first-val);
19 |
20 | @return (
21 | webkit-image: -webkit- + $prefix + ($offset - $num) + $suffix,
22 | spec-image: $image
23 | );
24 | }
25 | }
26 |
--------------------------------------------------------------------------------
/src/sass/bourbon/helpers/_linear-gradient-parser.scss:
--------------------------------------------------------------------------------
1 | @function _linear-gradient-parser($image) {
2 | $image: unquote($image);
3 | $gradients: ();
4 | $start: str-index($image, "(");
5 | $end: str-index($image, ",");
6 | $first-val: str-slice($image, $start + 1, $end - 1);
7 |
8 | $prefix: str-slice($image, 1, $start);
9 | $suffix: str-slice($image, $end, str-length($image));
10 |
11 | $has-multiple-vals: str-index($first-val, " ");
12 | $has-single-position: unquote(_position-flipper($first-val) + "");
13 | $has-angle: is-number(str-slice($first-val, 1, 1));
14 |
15 | @if $has-multiple-vals {
16 | $gradients: _linear-side-corner-parser($image, $first-val, $prefix, $suffix, $has-multiple-vals);
17 | }
18 |
19 | @else if $has-single-position != "" {
20 | $pos: unquote($has-single-position + "");
21 |
22 | $gradients: (
23 | webkit-image: -webkit- + $image,
24 | spec-image: $prefix + "to " + $pos + $suffix
25 | );
26 | }
27 |
28 | @else if $has-angle {
29 | // Rotate degree for webkit
30 | $gradients: _linear-angle-parser($image, $first-val, $prefix, $suffix);
31 | }
32 |
33 | @else {
34 | $gradients: (
35 | webkit-image: -webkit- + $image,
36 | spec-image: $image
37 | );
38 | }
39 |
40 | @return $gradients;
41 | }
42 |
--------------------------------------------------------------------------------
/src/sass/bourbon/helpers/_linear-positions-parser.scss:
--------------------------------------------------------------------------------
1 | @function _linear-positions-parser($pos) {
2 | $type: type-of(nth($pos, 1));
3 | $spec: null;
4 | $degree: null;
5 | $side: null;
6 | $corner: null;
7 | $length: length($pos);
8 | // Parse Side and corner positions
9 | @if ($length > 1) {
10 | @if nth($pos, 1) == "to" { // Newer syntax
11 | $side: nth($pos, 2);
12 |
13 | @if $length == 2 { // eg. to top
14 | // Swap for backwards compatibility
15 | $degree: _position-flipper(nth($pos, 2));
16 | }
17 | @else if $length == 3 { // eg. to top left
18 | $corner: nth($pos, 3);
19 | }
20 | }
21 | @else if $length == 2 { // Older syntax ("top left")
22 | $side: _position-flipper(nth($pos, 1));
23 | $corner: _position-flipper(nth($pos, 2));
24 | }
25 |
26 | @if ("#{$side} #{$corner}" == "left top") or ("#{$side} #{$corner}" == "top left") {
27 | $degree: _position-flipper(#{$side}) _position-flipper(#{$corner});
28 | }
29 | @else if ("#{$side} #{$corner}" == "right top") or ("#{$side} #{$corner}" == "top right") {
30 | $degree: _position-flipper(#{$side}) _position-flipper(#{$corner});
31 | }
32 | @else if ("#{$side} #{$corner}" == "right bottom") or ("#{$side} #{$corner}" == "bottom right") {
33 | $degree: _position-flipper(#{$side}) _position-flipper(#{$corner});
34 | }
35 | @else if ("#{$side} #{$corner}" == "left bottom") or ("#{$side} #{$corner}" == "bottom left") {
36 | $degree: _position-flipper(#{$side}) _position-flipper(#{$corner});
37 | }
38 | $spec: to $side $corner;
39 | }
40 | @else if $length == 1 {
41 | // Swap for backwards compatibility
42 | @if $type == string {
43 | $degree: $pos;
44 | $spec: to _position-flipper($pos);
45 | }
46 | @else {
47 | $degree: -270 - $pos; //rotate the gradient opposite from spec
48 | $spec: $pos;
49 | }
50 | }
51 | $degree: unquote($degree + ",");
52 | $spec: unquote($spec + ",");
53 | @return $degree $spec;
54 | }
55 |
56 | @function _position-flipper($pos) {
57 | @return if($pos == left, right, null)
58 | if($pos == right, left, null)
59 | if($pos == top, bottom, null)
60 | if($pos == bottom, top, null);
61 | }
62 |
--------------------------------------------------------------------------------
/src/sass/bourbon/helpers/_linear-side-corner-parser.scss:
--------------------------------------------------------------------------------
1 | // Private function for linear-gradient-parser
2 | @function _linear-side-corner-parser($image, $first-val, $prefix, $suffix, $has-multiple-vals) {
3 | $val-1: str-slice($first-val, 1, $has-multiple-vals - 1);
4 | $val-2: str-slice($first-val, $has-multiple-vals + 1, str-length($first-val));
5 | $val-3: null;
6 | $has-val-3: str-index($val-2, " ");
7 |
8 | @if $has-val-3 {
9 | $val-3: str-slice($val-2, $has-val-3 + 1, str-length($val-2));
10 | $val-2: str-slice($val-2, 1, $has-val-3 - 1);
11 | }
12 |
13 | $pos: _position-flipper($val-1) _position-flipper($val-2) _position-flipper($val-3);
14 | $pos: unquote($pos + "");
15 |
16 | // Use old spec for webkit
17 | @if $val-1 == "to" {
18 | @return (
19 | webkit-image: -webkit- + $prefix + $pos + $suffix,
20 | spec-image: $image
21 | );
22 | }
23 |
24 | // Bring the code up to spec
25 | @else {
26 | @return (
27 | webkit-image: -webkit- + $image,
28 | spec-image: $prefix + "to " + $pos + $suffix
29 | );
30 | }
31 | }
32 |
--------------------------------------------------------------------------------
/src/sass/bourbon/helpers/_radial-arg-parser.scss:
--------------------------------------------------------------------------------
1 | @function _radial-arg-parser($g1, $g2, $pos, $shape-size) {
2 | @each $value in $g1, $g2 {
3 | $first-val: nth($value, 1);
4 | $pos-type: type-of($first-val);
5 | $spec-at-index: null;
6 |
7 | // Determine if spec was passed to mixin
8 | @if type-of($value) == list {
9 | $spec-at-index: if(index($value, at), index($value, at), false);
10 | }
11 | @if $spec-at-index {
12 | @if $spec-at-index > 1 {
13 | @for $i from 1 through ($spec-at-index - 1) {
14 | $shape-size: $shape-size nth($value, $i);
15 | }
16 | @for $i from ($spec-at-index + 1) through length($value) {
17 | $pos: $pos nth($value, $i);
18 | }
19 | }
20 | @else if $spec-at-index == 1 {
21 | @for $i from ($spec-at-index + 1) through length($value) {
22 | $pos: $pos nth($value, $i);
23 | }
24 | }
25 | $g1: null;
26 | }
27 |
28 | // If not spec calculate correct values
29 | @else {
30 | @if ($pos-type != color) or ($first-val != "transparent") {
31 | @if ($pos-type == number)
32 | or ($first-val == "center")
33 | or ($first-val == "top")
34 | or ($first-val == "right")
35 | or ($first-val == "bottom")
36 | or ($first-val == "left") {
37 |
38 | $pos: $value;
39 |
40 | @if $pos == $g1 {
41 | $g1: null;
42 | }
43 | }
44 |
45 | @else if
46 | ($first-val == "ellipse")
47 | or ($first-val == "circle")
48 | or ($first-val == "closest-side")
49 | or ($first-val == "closest-corner")
50 | or ($first-val == "farthest-side")
51 | or ($first-val == "farthest-corner")
52 | or ($first-val == "contain")
53 | or ($first-val == "cover") {
54 |
55 | $shape-size: $value;
56 |
57 | @if $value == $g1 {
58 | $g1: null;
59 | }
60 |
61 | @else if $value == $g2 {
62 | $g2: null;
63 | }
64 | }
65 | }
66 | }
67 | }
68 | @return $g1, $g2, $pos, $shape-size;
69 | }
70 |
--------------------------------------------------------------------------------
/src/sass/bourbon/helpers/_radial-gradient-parser.scss:
--------------------------------------------------------------------------------
1 | @function _radial-gradient-parser($image) {
2 | $image: unquote($image);
3 | $gradients: ();
4 | $start: str-index($image, "(");
5 | $end: str-index($image, ",");
6 | $first-val: str-slice($image, $start + 1, $end - 1);
7 |
8 | $prefix: str-slice($image, 1, $start);
9 | $suffix: str-slice($image, $end, str-length($image));
10 |
11 | $is-spec-syntax: str-index($first-val, "at");
12 |
13 | @if $is-spec-syntax and $is-spec-syntax > 1 {
14 | $keyword: str-slice($first-val, 1, $is-spec-syntax - 2);
15 | $pos: str-slice($first-val, $is-spec-syntax + 3, str-length($first-val));
16 | $pos: append($pos, $keyword, comma);
17 |
18 | $gradients: (
19 | webkit-image: -webkit- + $prefix + $pos + $suffix,
20 | spec-image: $image
21 | );
22 | }
23 |
24 | @else if $is-spec-syntax == 1 {
25 | $pos: str-slice($first-val, $is-spec-syntax + 3, str-length($first-val));
26 |
27 | $gradients: (
28 | webkit-image: -webkit- + $prefix + $pos + $suffix,
29 | spec-image: $image
30 | );
31 | }
32 |
33 | @else if str-index($image, "cover") or str-index($image, "contain") {
34 | @warn "Radial-gradient needs to be updated to conform to latest spec.";
35 |
36 | $gradients: (
37 | webkit-image: null,
38 | spec-image: $image
39 | );
40 | }
41 |
42 | @else {
43 | $gradients: (
44 | webkit-image: -webkit- + $image,
45 | spec-image: $image
46 | );
47 | }
48 |
49 | @return $gradients;
50 | }
51 |
--------------------------------------------------------------------------------
/src/sass/bourbon/helpers/_radial-positions-parser.scss:
--------------------------------------------------------------------------------
1 | @function _radial-positions-parser($gradient-pos) {
2 | $shape-size: nth($gradient-pos, 1);
3 | $pos: nth($gradient-pos, 2);
4 | $shape-size-spec: _shape-size-stripper($shape-size);
5 |
6 | $pre-spec: unquote(if($pos, "#{$pos}, ", null))
7 | unquote(if($shape-size, "#{$shape-size},", null));
8 | $pos-spec: if($pos, "at #{$pos}", null);
9 |
10 | $spec: "#{$shape-size-spec} #{$pos-spec}";
11 |
12 | // Add comma
13 | @if ($spec != " ") {
14 | $spec: "#{$spec},";
15 | }
16 |
17 | @return $pre-spec $spec;
18 | }
19 |
--------------------------------------------------------------------------------
/src/sass/bourbon/helpers/_render-gradients.scss:
--------------------------------------------------------------------------------
1 | // User for linear and radial gradients within background-image or border-image properties
2 |
3 | @function _render-gradients($gradient-positions, $gradients, $gradient-type, $vendor: false) {
4 | $pre-spec: null;
5 | $spec: null;
6 | $vendor-gradients: null;
7 | @if $gradient-type == linear {
8 | @if $gradient-positions {
9 | $pre-spec: nth($gradient-positions, 1);
10 | $spec: nth($gradient-positions, 2);
11 | }
12 | }
13 | @else if $gradient-type == radial {
14 | $pre-spec: nth($gradient-positions, 1);
15 | $spec: nth($gradient-positions, 2);
16 | }
17 |
18 | @if $vendor {
19 | $vendor-gradients: -#{$vendor}-#{$gradient-type}-gradient(#{$pre-spec} $gradients);
20 | }
21 | @else if $vendor == false {
22 | $vendor-gradients: "#{$gradient-type}-gradient(#{$spec} #{$gradients})";
23 | $vendor-gradients: unquote($vendor-gradients);
24 | }
25 | @return $vendor-gradients;
26 | }
27 |
--------------------------------------------------------------------------------
/src/sass/bourbon/helpers/_shape-size-stripper.scss:
--------------------------------------------------------------------------------
1 | @function _shape-size-stripper($shape-size) {
2 | $shape-size-spec: null;
3 | @each $value in $shape-size {
4 | @if ($value == "cover") or ($value == "contain") {
5 | $value: null;
6 | }
7 | $shape-size-spec: "#{$shape-size-spec} #{$value}";
8 | }
9 | @return $shape-size-spec;
10 | }
11 |
--------------------------------------------------------------------------------
/src/sass/bourbon/helpers/_str-to-num.scss:
--------------------------------------------------------------------------------
1 | //************************************************************************//
2 | // Helper function for linear/radial-gradient-parsers.
3 | // Source: http://sassmeister.com/gist/9647408
4 | //************************************************************************//
5 | @function _str-to-num($string) {
6 | // Matrices
7 | $strings: "0" "1" "2" "3" "4" "5" "6" "7" "8" "9";
8 | $numbers: 0 1 2 3 4 5 6 7 8 9;
9 |
10 | // Result
11 | $result: 0;
12 | $divider: 0;
13 | $minus: false;
14 |
15 | // Looping through all characters
16 | @for $i from 1 through str-length($string) {
17 | $character: str-slice($string, $i, $i);
18 | $index: index($strings, $character);
19 |
20 | @if $character == "-" {
21 | $minus: true;
22 | }
23 |
24 | @else if $character == "." {
25 | $divider: 1;
26 | }
27 |
28 | @else {
29 | @if not $index {
30 | $result: if($minus, $result * -1, $result);
31 | @return _convert-units($result, str-slice($string, $i));
32 | }
33 |
34 | $number: nth($numbers, $index);
35 |
36 | @if $divider == 0 {
37 | $result: $result * 10;
38 | }
39 |
40 | @else {
41 | // Move the decimal dot to the left
42 | $divider: $divider * 10;
43 | $number: $number / $divider;
44 | }
45 |
46 | $result: $result + $number;
47 | }
48 | }
49 | @return if($minus, $result * -1, $result);
50 | }
51 |
--------------------------------------------------------------------------------
/src/sass/bourbon/settings/_asset-pipeline.scss:
--------------------------------------------------------------------------------
1 | @charset "UTF-8";
2 |
3 | /// A global setting to enable or disable the `$asset-pipeline` variable for all functions that accept it.
4 | ///
5 | /// @type Bool
6 |
7 | $asset-pipeline: false !default;
8 |
--------------------------------------------------------------------------------
/src/sass/bourbon/settings/_prefixer.scss:
--------------------------------------------------------------------------------
1 | @charset "UTF-8";
2 |
3 | /// Global variables to enable or disable vendor prefixes
4 |
5 | $prefix-for-webkit: true !default;
6 | $prefix-for-mozilla: true !default;
7 | $prefix-for-microsoft: true !default;
8 | $prefix-for-opera: true !default;
9 | $prefix-for-spec: true !default;
10 |
--------------------------------------------------------------------------------
/src/sass/bourbon/settings/_px-to-em.scss:
--------------------------------------------------------------------------------
1 | $em-base: 16px !default;
2 |
--------------------------------------------------------------------------------
/src/sass/spreadIt.scss:
--------------------------------------------------------------------------------
1 | @import 'bourbon/bourbon';
2 | @import 'columnManager';
3 | @import 'dropzone';
4 |
5 | $arrowFontsDir: '../fonts/arrows' !default;
6 |
7 | @font-face {
8 | font-family: 'Arrows';
9 | src:
10 | url($arrowFontsDir + '/select-arrows.ttf?lym46w') format('truetype'),
11 | url($arrowFontsDir + '/select-arrows.woff?lym46w') format('woff'),
12 | url($arrowFontsDir + '/select-arrows.svg?lym46w#select-arrows') format('svg');
13 | font-weight: normal;
14 | font-style: normal;
15 | }
16 |
17 |
--------------------------------------------------------------------------------
/src/siColumnManager.directive.js:
--------------------------------------------------------------------------------
1 | +function () {
2 | 'use strict';
3 |
4 | angular.module('bg.spreadit').directive("siColumnManager", ['$timeout', '$parse', '$rootScope', directive]);
5 |
6 | function directive($timeout, $parse, $rootScope) {
7 | var supports = {
8 | xls: !!(window.XLSX && XLSX.utils),
9 | csv: !!(window.Papa && Papa.parse)
10 | };
11 |
12 | return {
13 | restrict: 'E',
14 | scope: {
15 | id: '@?siId',
16 | callback: '&?siChange',
17 | columns: '=?siColumns',
18 | sampleSize: '=?siSampleSize',
19 | excludeUnknownColumns: '=?siExcludeUnknownColumns',
20 | allowRenaming: '=?siAllowRenaming',
21 | // TODO: add support for these flags
22 | unknownColumnsGroupName: '=?siUnknownColumnsGroupName',
23 | groupUnknownColumns: '=?siGroupUnknownColumns',
24 | postProcessors: '=?siPostProcessors'
25 | },
26 | controller: ['$scope', '$element', '$attrs', controller],
27 | controllerAs: 'vm',
28 | templateUrl: '/columnManager.html'
29 | };
30 |
31 | function controller($scope, $element, $attrs) {
32 |
33 | _.defaults($scope, {
34 | id: "",
35 | columns: [],
36 | postProcessors: [],
37 | sampleSize: 3,
38 | excludeUnknownColumns: false,
39 | allowCustomRenaming: true,
40 | unknownColumnGroupName: '$extras',
41 | groupUnknownColumns: false,
42 | callback: angular.noop
43 | });
44 |
45 | var self = this;
46 | var columnMap = $scope.columns.reduce(function (map, entry) {
47 |
48 | var val;
49 | if (angular.isString(entry)) {
50 | val = {
51 | title: entry,
52 | property: entry
53 | };
54 | } else {
55 | val = entry;
56 | }
57 |
58 | map[String(val.property).trim().toLowerCase()] = val;
59 | map[String(val.title).trim().toLowerCase()] = val;
60 | if (angular.isArray(entry.aliases)) {
61 | entry.aliases.forEach(function (alias) {
62 | map[String(alias).trim().toLowerCase()] = val;
63 | });
64 | }
65 | return map;
66 | }, {});
67 | var titles = _.flatten($scope.columns.map(function (v) {
68 | if (angular.isString(v)) {
69 | return v;
70 | } else if (angular.isArray(v.aliases)) {
71 | return v.aliases.concat(v.title);
72 | } else {
73 | return v.title;
74 | }
75 | })).map(function (v) {
76 | return String(v).trim().toLowerCase();
77 | });
78 |
79 | var presult;
80 | var $file;
81 |
82 | $scope.$watch('hasHeader', function () {
83 |
84 | if ($file && self.active) {
85 | parseFile($file);
86 | }
87 | });
88 |
89 | this.remap = function (mapping) {
90 |
91 | remap(mapping);
92 | this.active = false;
93 | $element.removeClass('active');
94 | };
95 |
96 | this.cancel = function () {
97 | this.active = false;
98 | $element.removeClass('active');
99 | };
100 |
101 | function isHeader(values) {
102 |
103 | var isIt = $scope.hasHeader || values.some(function (value) {
104 | return titles.indexOf(String(value).trim().toLowerCase()) !== -1;
105 | });
106 | $scope.hasHeader = isIt;
107 | return isIt;
108 | }
109 |
110 | function isExcel(data) {
111 | return [0xD0, 0x09, 0x3C, 0x50].indexOf(data.charCodeAt(0)) !== -1;
112 | }
113 |
114 | function parseFile(file) {
115 |
116 | if (!file) {
117 | return;
118 | }
119 |
120 | var reader = new FileReader();
121 |
122 | if (reader.readAsBinaryString) {
123 |
124 | reader.onload = function (e) {
125 | preparse(file, e.target.result);
126 | };
127 |
128 | reader.readAsBinaryString(file);
129 | } else {
130 |
131 | reader.onload = function (e) {
132 |
133 | /* convert data to binary string */
134 | var data = new Uint8Array(e.target.result);
135 | var buffer = [];
136 | var i;
137 | for (i = 0; i < data.length; i++) {
138 | buffer[i] = String.fromCharCode(data[i]);
139 | }
140 | preparse(file, buffer.join(''));
141 | };
142 | reader.readAsArrayBuffer(file)
143 | }
144 | }
145 |
146 | function preparse(file, content) {
147 |
148 | if (supports.xls && isExcel(content)) {
149 | preparseExcel(content);
150 | } else if (supports.csv) {
151 | preparseCSV(file);
152 | }
153 | }
154 |
155 |
156 | function preparseExcel(content) {
157 |
158 | var c;
159 | var workbook = XLSX.read(content, {
160 | type: 'binary',
161 | sheetRows: $scope.sampleSize + 1,
162 | cellHTML: false,
163 | cellFormula: false
164 | });
165 | var sheet = workbook.Sheets[workbook.SheetNames[0]];
166 | var headerRange = XLSX.utils.decode_range(sheet['!ref']);
167 | var firstRow = [];
168 | var r = headerRange.s.r;
169 | for (c = headerRange.s.c; c < headerRange.e.c; c++) {
170 | var cell = sheet[XLSX.utils.encode_cell({r: r, c: c})];
171 | firstRow.push(cell ? String(cell.v).toLowerCase() : null);
172 | }
173 |
174 | var headers;
175 | var i = 1;
176 | if (!isHeader(firstRow)) {
177 | headers = [];
178 | for (c = headerRange.s.c; c <= headerRange.e.c; c++) {
179 | headers.push('Column ' + i++);
180 | }
181 | }
182 | var data = XLSX.utils.sheet_to_json(sheet, {
183 | header: headers,
184 | range: 0
185 | }).slice(0, 3);
186 |
187 | if ($scope.debug) {
188 | window.$spreadIt = {
189 | workbook: workbook,
190 | sheet: sheet,
191 | content: content
192 | }
193 | }
194 | preview({
195 | type: 'excel',
196 | raw: content,
197 | data: data,
198 | headers: headers || Object.keys(data[0])
199 | });
200 | }
201 |
202 | function preparseCsvWithHeader(file) {
203 |
204 | Papa.parse(file, {
205 | header: true,
206 | preview: $scope.sampleSize,
207 | complete: function (result) {
208 |
209 | var headers = Object.keys(result.data[0]);
210 | preview({
211 | type: 'csv',
212 | data: result.data,
213 | raw: file,
214 | headers: headers
215 | });
216 | }
217 | });
218 | }
219 |
220 | function preparseCsvSansHeader(file) {
221 |
222 | Papa.parse(file, {
223 | header: false,
224 | preview: $scope.sampleSize,
225 | complete: function (result) {
226 |
227 | var headers = result.data[0].map(function (column, i) {
228 | return 'Column ' + (i + 1);
229 | });
230 |
231 | var data = result.data.map(function (columns) {
232 |
233 | var obj = {};
234 | columns.forEach(function (column, i) {
235 | obj['Column ' + (i + 1)] = column;
236 | });
237 | return obj;
238 | });
239 | preview({
240 | type: 'csv',
241 | headers: headers,
242 | data: data,
243 | raw: file
244 | });
245 | }
246 | });
247 | }
248 |
249 | function preparseCSV(file) {
250 | Papa.parse(file, {
251 | preview: 1,
252 | complete: function (result) {
253 | var firstRow = result.data[0];
254 | if (firstRow && isHeader(firstRow)) {
255 | preparseCsvWithHeader(file);
256 | } else {
257 | preparseCsvSansHeader(file);
258 | }
259 | }
260 | });
261 | }
262 |
263 | function parseExcel(content, headers) {
264 | var c;
265 | var workbook = XLSX.read(content, {
266 | type: 'binary',
267 | cellHTML: false,
268 | cellFormula: false
269 | });
270 | var sheet = workbook.Sheets[workbook.SheetNames[0]];
271 | var headerRange = XLSX.utils.decode_range(sheet['!ref']);
272 | var firstRow = [];
273 | var r = headerRange.s.r;
274 | for (c = headerRange.s.c; c < headerRange.e.c; c++) {
275 | var cell = sheet[XLSX.utils.encode_cell({r: r, c: c})];
276 | firstRow.push(cell ? String(cell.v).toLowerCase() : null);
277 | }
278 |
279 | var data = XLSX.utils.sheet_to_json(sheet, {
280 | header: headers,
281 | range: isHeader(firstRow) ? 1 : 0
282 | }).map(function (result) {
283 |
284 | delete result.$skip$;
285 | return result;
286 | });
287 |
288 |
289 | $scope.callback({
290 | $type: 'excel',
291 | $file: $file,
292 | $data: postProcess(data)
293 | });
294 | }
295 |
296 | function parseCsv(file, headers) {
297 |
298 | Papa.parse(file, {
299 | header: false,
300 | complete: function (result) {
301 |
302 | var firstRow = result.data[0];
303 | if (isHeader(firstRow)) {
304 | result.data.splice(0, 1);
305 | }
306 | var data = result.data.map(function (columns) {
307 |
308 | var obj = {};
309 | columns.forEach(function (column, i) {
310 |
311 | if (headers[i] !== '$skip$') {
312 | obj[headers[i]] = column;
313 | }
314 | });
315 | return obj;
316 | });
317 | $scope.callback({
318 | $type: 'csv',
319 | $file: $file,
320 | $data: postProcess(data)
321 | });
322 | }
323 | });
324 | }
325 |
326 | function preview(result) {
327 |
328 | $timeout(function () {
329 |
330 | var preview = self.preview = [];
331 |
332 | result.headers.forEach(function (header) {
333 |
334 | var normalizedHeader = header.toLowerCase().trim();
335 | var mapping;
336 | if (columnMap[normalizedHeader]) {
337 | mapping = columnMap[normalizedHeader];
338 | } else if ($scope.excludeUnknownColumns) {
339 | mapping = {
340 | title: 'Ignore This Column',
341 | property: '$skip$'
342 | }
343 | } else {
344 | mapping = {
345 | title: 'Keep This Column',
346 | property: false
347 | };
348 | }
349 | preview.push({
350 | header: header,
351 | mapping: mapping,
352 | custom: header,
353 | sample: result.data.map(function (v) {
354 | return v[header];
355 | })
356 | });
357 | });
358 | var titles = [];
359 | if (!$scope.excludeUnknownColumns) {
360 | titles.push({
361 | title: 'Keep This Column',
362 | property: false
363 | });
364 | }
365 |
366 | titles.push({
367 | title: 'Ignore This Column',
368 | property: '$skip$'
369 | });
370 |
371 | if (!$scope.excludeUnknownColumns && $scope.allowCustomRenaming) {
372 | titles.push({
373 | title: 'Rename This Column',
374 | property: '$rename$'
375 | });
376 | }
377 |
378 | self.titles = titles.concat($scope.columns.map(function (column) {
379 |
380 | if (angular.isObject(column)) {
381 | return column;
382 | }
383 |
384 | return {
385 | title: column,
386 | property: column
387 | }
388 | }));
389 | presult = result;
390 | });
391 | }
392 |
393 | function remap(mapping) {
394 |
395 | var headers = mapping.map(function (column) {
396 |
397 | var mapping = column.mapping;
398 | if (mapping.property === false) {
399 | return column.header;
400 | } else if (mapping.property === '$rename$') {
401 | return column.custom;
402 | } else {
403 | return column.mapping.property;
404 | }
405 | });
406 | if (presult.type === 'csv') {
407 | parseCsv(presult.raw, headers);
408 | } else {
409 | parseExcel(presult.raw, headers);
410 | }
411 | }
412 |
413 | $rootScope.$on('si.preview', function (e, id, file) {
414 |
415 | if (file && id === $scope.id) {
416 | $file = file;
417 | $scope.hasHeader = false;
418 | parseFile(file);
419 | self.active = true;
420 | $element.addClass('active');
421 | }
422 | });
423 |
424 | function postProcess(data) {
425 |
426 | if(!$scope.postProcessors.length) {
427 | return data;
428 | }
429 |
430 | return data.map(function(obj) {
431 |
432 | $scope.postProcessors.forEach(function(fn) {
433 | fn(obj);
434 | });
435 | return obj;
436 | })
437 | }
438 | }
439 | }
440 |
441 | }();
442 |
--------------------------------------------------------------------------------
/src/siDropZone.directive.js:
--------------------------------------------------------------------------------
1 | +function () {
2 | 'use strict';
3 |
4 | angular.module('bg.spreadit').directive("siDropzone", ['$rootScope', directive]);
5 | angular.module('bg.spreadit').directive("siImporter", ['$rootScope', directive]);
6 |
7 | function directive($rootScope) {
8 | var accepts = [];
9 |
10 | if(!!(window.XLSX && XLSX.utils)) {
11 | accepts.push('.xls', '.xlsx');
12 | }
13 |
14 | if(!!(window.Papa && Papa.parse)) {
15 | accepts.push('.csv', '.tsv', '.txt');
16 | }
17 |
18 | return {
19 | restrict: 'E',
20 | scope: {
21 | id: '@siId'
22 | },
23 | controller: controller,
24 | controllerAs: 'vm',
25 | templateUrl: '/dropzone.html',
26 | link: link
27 | };
28 |
29 | function controller() {
30 |
31 | }
32 |
33 | function link($scope, $element, $attrs) {
34 |
35 | _.defaults($scope, {
36 | id: ""
37 | });
38 |
39 | var element = $element[0];
40 | element.setAttribute('accepts', accepts.join());
41 | element.querySelector('input[type="file"]').addEventListener('change', function (e) {
42 | $rootScope.$emit('si.preview', $scope.id, e.target.files[0]);
43 | });
44 | }
45 | }
46 |
47 | }();
48 |
--------------------------------------------------------------------------------
/src/siTrigger.directive.js:
--------------------------------------------------------------------------------
1 | +function () {
2 | 'use strict';
3 |
4 | angular.module('bg.spreadit').directive("siFileSelect", ['$rootScope', directive]);
5 | angular.module('bg.spreadit').directive("siTrigger", ['$rootScope', directive]);
6 |
7 | function directive($rootScope) {
8 | var accepts = [];
9 |
10 | if(!!(window.XLSX && XLSX.utils)) {
11 | accepts.push('.xls', '.xlsx');
12 | }
13 |
14 | if(!!(window.Papa && Papa.parse)) {
15 | accepts.push('.csv', '.tsv', '.txt');
16 | }
17 |
18 | return {
19 | restrict: 'EA',
20 | scope: {
21 | id: '@?siFileSelect'
22 | },
23 | link: link
24 | };
25 |
26 | function link($scope, $element, $attrs) {
27 |
28 | var element = $element[0];
29 | var fileEl = $element;
30 | var tagName = element.tagName.toLowerCase();
31 | var isFileInput = tagName === 'input' && $attrs.type && $attrs.type.toLowerCase() === 'file';
32 | var isLink = tagName === 'a';
33 |
34 | if(angular.isDefined($attrs.siFileSelect)) {
35 | $scope.id = $attrs.siFileSelect;
36 | }
37 |
38 | if (!isFileInput) {
39 | fileEl = angular.element('');
40 | var label = angular.element('');
41 | label.css('visibility', 'hidden').css('position', 'absolute').css('overflow', 'hidden')
42 | .css('width', '0px').css('height', '0px').css('border', 'none')
43 | .css('margin', '0px').css('padding', '0px').attr('tabindex', '-1');
44 | document.body.appendChild(label.append(fileEl)[0]);
45 | $element.on('click', function(e) {
46 | e.preventDefault();
47 | fileEl[0].click();
48 | });
49 | }
50 |
51 | if(isLink) {
52 | $element.attr('href', 'javascript:');
53 | }
54 |
55 | fileEl.attr('accepts', accepts.join());
56 | fileEl.on('change', onChange);
57 |
58 | function onChange(e) {
59 | $rootScope.$emit('si.preview', $scope.id, e.target.files[0]);
60 | }
61 | }
62 | }
63 |
64 | }();
65 |
--------------------------------------------------------------------------------
/src/spreadIt.service.js:
--------------------------------------------------------------------------------
1 | +function () {
2 | 'use strict';
3 |
4 | angular.module('bg.spreadit').service("Spreadit", ['$rootScope', service]);
5 |
6 | function service($rootScope) {
7 |
8 | }
9 |
10 | }();
11 |
--------------------------------------------------------------------------------