├── .gitignore ├── CODEOWNERS ├── src ├── styles │ └── main.scss └── index.html ├── app.json ├── design-tokens ├── text.json ├── app.json ├── aliases.json ├── spacing.json ├── font.json └── border.json ├── server.js ├── package.json ├── README.md ├── CONTRIBUTING.md ├── LICENSE.txt └── gulpfile.js /.gitignore: -------------------------------------------------------------------------------- 1 | .generated 2 | .www 3 | node_modules 4 | npm-debug.log 5 | -------------------------------------------------------------------------------- /CODEOWNERS: -------------------------------------------------------------------------------- 1 | # Comment line immediately above ownership line is reserved for related gus information. Please be careful while editing. 2 | #ECCN:Open Source 3 | -------------------------------------------------------------------------------- /src/styles/main.scss: -------------------------------------------------------------------------------- 1 | @import ".generated/app"; 2 | 3 | body { 4 | padding: $spacing-medium; 5 | color: $color-text; 6 | font-family: sans-serif; 7 | } 8 | -------------------------------------------------------------------------------- /app.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "theo-example", 3 | "scripts": { 4 | }, 5 | "env": { 6 | "PORT": "80" 7 | }, 8 | "formation": { 9 | }, 10 | "addons": [ 11 | 12 | ], 13 | "buildpacks": [ 14 | { 15 | "url": "heroku/nodejs" 16 | } 17 | ] 18 | } 19 | -------------------------------------------------------------------------------- /design-tokens/text.json: -------------------------------------------------------------------------------- 1 | { 2 | "global": { 3 | "type": "color", 4 | "category": "text-color" 5 | }, 6 | "imports": [ 7 | "./aliases.json" 8 | ], 9 | "props": { 10 | "COLOR_TEXT": { 11 | "value": "{!NEVADA}" 12 | }, 13 | "COLOR_TEXT_ALT": { 14 | "value": "{!BLUE_BAYOUX}" 15 | } 16 | } 17 | } -------------------------------------------------------------------------------- /src/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 |

Welcome to Theo!

10 |

Check out your style guide!

11 | 12 | -------------------------------------------------------------------------------- /design-tokens/app.json: -------------------------------------------------------------------------------- 1 | { 2 | "imports": [ 3 | "./aliases.json", 4 | "./border.json", 5 | "./font.json", 6 | "./spacing.json", 7 | "./text.json" 8 | ], 9 | "props": { 10 | "COLOR_BRAND": { 11 | "value": "{!CASPER}", 12 | "type": "color", 13 | "category": "background-color", 14 | "comment": "Some comment about how to use it." 15 | } 16 | } 17 | } -------------------------------------------------------------------------------- /design-tokens/aliases.json: -------------------------------------------------------------------------------- 1 | { 2 | "aliases": { 3 | "PORCELAIN": "#f5f6f7", 4 | "PALE_ROYAL_BLUE": "#F0F1F2", 5 | "GEYSER": "#DADEE2", 6 | "CASPER": "#9FAAB5", 7 | "REGENT_GREY": "#8595A6", 8 | "SLATE_GREY": "#66788A", 9 | "NEVADA": "#686C70", 10 | "BLUE_BAYOUX": "#485C70", 11 | "GREY_ROYAL_BLUE": "#34495E", 12 | "DARK_GREY_ROYAL_BLUE": "#2A4158", 13 | "ROLLING_STONE": "#525354" 14 | } 15 | } -------------------------------------------------------------------------------- /server.js: -------------------------------------------------------------------------------- 1 | const express = require('express') 2 | const app = express() 3 | 4 | app.set('port', process.env.PORT || 3000) 5 | 6 | app.use(require('connect-livereload')({ 7 | port: 35729 8 | })) 9 | 10 | app.use(express['static']('./.www')) 11 | app.use('/generated', express['static']('./.generated')) 12 | 13 | const port = app.get('port') 14 | 15 | app.listen(port, () => console.log('The app is running at: http://localhost:' + port)) 16 | -------------------------------------------------------------------------------- /design-tokens/spacing.json: -------------------------------------------------------------------------------- 1 | { 2 | "global": { 3 | "type": "size", 4 | "category": "spacing" 5 | }, 6 | "props": { 7 | "SPACING_XX_SMALL": { 8 | "value": "2px" 9 | }, 10 | "SPACING_X_SMALL": { 11 | "value": "7px" 12 | }, 13 | "SPACING_SMALL": { 14 | "value": "8px" 15 | }, 16 | "SPACING_MEDIUM": { 17 | "value": "14px" 18 | }, 19 | "SPACING_LARGE": { 20 | "value": "18px" 21 | }, 22 | "SPACING_X_LARGE": { 23 | "value": "28px" 24 | } 25 | } 26 | } -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "theo-example", 3 | "version": "1.0.0", 4 | "description": "Example on how to develop a design system using Theo.", 5 | "license": "BSD-3-Clause", 6 | "dependencies": { 7 | "connect-livereload": "^0.6.0", 8 | "del": "^2.2.2", 9 | "express": "^4.14.0", 10 | "gulp": "^3.9.1", 11 | "gulp-livereload": "^3.8.1", 12 | "gulp-sass": "^3.1.0", 13 | "run-sequence": "^1.2.2", 14 | "theo": "^5.0.0" 15 | }, 16 | "scripts": { 17 | "dev": "gulp dev", 18 | "prestart": "gulp" 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /design-tokens/font.json: -------------------------------------------------------------------------------- 1 | { 2 | "global": { 3 | "type": "size", 4 | "category": "font-size" 5 | }, 6 | "props": { 7 | "FONT_SIZE_XX_SMALL": { 8 | "value": "10px" 9 | }, 10 | "FONT_SIZE_X_SMALL": { 11 | "value": "13px" 12 | }, 13 | "FONT_SIZE_SMALL": { 14 | "value": "14px" 15 | }, 16 | "FONT_SIZE_MEDIUM": { 17 | "value": "15px" 18 | }, 19 | "FONT_SIZE_LARGE": { 20 | "value": "16px" 21 | }, 22 | "FONT_SIZE_X_LARGE": { 23 | "value": "18px" 24 | }, 25 | "FONT_SIZE_XX_LARGE": { 26 | "value": "22px" 27 | } 28 | } 29 | } -------------------------------------------------------------------------------- /design-tokens/border.json: -------------------------------------------------------------------------------- 1 | { 2 | "imports": [ 3 | "./aliases.json" 4 | ], 5 | "props": { 6 | "BORDER_RADIUS_SMALL": { 7 | "value": "3px", 8 | "type": "size", 9 | "category": "radius" 10 | }, 11 | "BORDER_RADIUS_MEDIUM": { 12 | "value": "5px", 13 | "type": "size", 14 | "category": "radius" 15 | }, 16 | "BORDER_RADIUS_LARGE": { 17 | "value": "8px", 18 | "type": "size", 19 | "category": "radius" 20 | }, 21 | "BORDER_RADIUS_CIRCLE": { 22 | "value": "50%", 23 | "type": "size", 24 | "category": "radius" 25 | }, 26 | "COLOR_BORDER_SEPARATOR": { 27 | "value": "{!PORCELAIN}", 28 | "type": "color", 29 | "category": "hr-color" 30 | }, 31 | "COLOR_BORDER": { 32 | "value": "{!PORCELAIN}", 33 | "type": "color", 34 | "category": "border-color" 35 | } 36 | } 37 | } -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Theo Example 2 | 3 | Example project for integrating Design Tokens using [theo](https://github.com/salesforce-ux/theo). 4 | 5 | ## Setup 6 | 7 | ```bash 8 | $ git clone https://github.com/salesforce-ux/theo-example.git 9 | $ cd theo-example 10 | $ npm install 11 | ``` 12 | 13 | ## Development 14 | 15 | While developing your website or Design Tokens use `npm run dev` 16 | and then open [localhost:3000](http://localhost:3000). 17 | 18 | Now you can start editing your `src/index.html` and `src/styles/main.scss`. 19 | 20 | To see the generated docs for your Design Tokens go to [localhost:3000/generated/app.html](http://localhost:3000/generated/app.html). 21 | Note: You can change your Design Tokens in `./design-tokens/app.json` or 22 | the `./design-tokens/aliases.json` and see live changes to the docs. 23 | 24 | Further if you open [localhost:3000](http://localhost:3000) and change the Design Tokens, 25 | the updates are reflected live. 26 | -------------------------------------------------------------------------------- /CONTRIBUTING.md: -------------------------------------------------------------------------------- 1 | # Contributing Code 2 | 3 | External contributors are required to sign a Contributor’s License Agreement. 4 | You will be prompted to sign it when you open a pull request. 5 | 6 | 1. Create a new issue before starting your project so that we can keep 7 | track of what you are trying to add/fix. That way, we can also offer 8 | suggestions or let you know if there is already an effort in progress. 9 | 2. Fork off this repository. 10 | 3. Create a topic branch for the issue that you are trying to add. 11 | When possible, you should branch off the default branch. 12 | 4. Edit the code in your fork. 13 | 5. Send us a well documented pull request when you are done. 14 | 15 | The **GitHub pull requests** should meet the following criteria: 16 | 17 | - Descriptive title 18 | - Brief summary 19 | - @mention several relevant people to review the code 20 | - Add helpful GitHub comments on lines that you have questions / concerns about 21 | 22 | We’ll review your code, suggest any needed changes, and merge it in. Thank you. 23 | -------------------------------------------------------------------------------- /LICENSE.txt: -------------------------------------------------------------------------------- 1 | Copyright (c) 2014-present, Salesforce.com, Inc. 2 | All rights reserved. 3 | 4 | Redistribution and use in source and binary forms, with or without 5 | modification, are permitted provided that the following conditions are met: 6 | * Redistributions of source code must retain the above copyright 7 | notice, this list of conditions and the following disclaimer. 8 | * Redistributions in binary form must reproduce the above copyright 9 | notice, this list of conditions and the following disclaimer in the 10 | documentation and/or other materials provided with the distribution. 11 | * Neither the name of the Salesforce.com nor the 12 | names of its contributors may be used to endorse or promote products 13 | derived from this software without specific prior written permission. 14 | 15 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND 16 | ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 17 | WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 18 | DISCLAIMED. IN NO EVENT SHALL COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY 19 | DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 20 | (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 21 | LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND 22 | ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 23 | (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 24 | SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 25 | -------------------------------------------------------------------------------- /gulpfile.js: -------------------------------------------------------------------------------- 1 | const fs = require('fs') 2 | const path = require('path') 3 | 4 | const runSequence = require('run-sequence') 5 | const del = require('del') 6 | 7 | const gulp = require('gulp') 8 | const sass = require('gulp-sass') 9 | const livereload = require('gulp-livereload') 10 | 11 | const theo = require('theo') 12 | 13 | //////////////////////////////////////////////////////////////////// 14 | // Paths 15 | //////////////////////////////////////////////////////////////////// 16 | 17 | const paths = { 18 | designTokens: './design-tokens', 19 | generated: './.generated', 20 | output: './.www' 21 | } 22 | 23 | //////////////////////////////////////////////////////////////////// 24 | // Tasks - Clean 25 | //////////////////////////////////////////////////////////////////// 26 | 27 | gulp.task('clean', () => del([paths.generated, paths.output])) 28 | 29 | //////////////////////////////////////////////////////////////////// 30 | // Tasks - Design Tokens 31 | //////////////////////////////////////////////////////////////////// 32 | 33 | gulp.task('design-tokens', ['styleguide'], () => 34 | gulp.src('./design-tokens/app.json') 35 | .pipe(theo.plugins.transform('web')) 36 | .pipe(theo.plugins.format('scss')) 37 | .pipe(gulp.dest(paths.generated)) 38 | ) 39 | 40 | gulp.task('styleguide', () => 41 | gulp.src('./design-tokens/app.json') 42 | .pipe(theo.plugins.transform('web')) 43 | .pipe(theo.plugins.format('html')) 44 | .pipe(gulp.dest(paths.generated)) 45 | .pipe(livereload()) 46 | ) 47 | 48 | //////////////////////////////////////////////////////////////////// 49 | // Tasks - Site 50 | //////////////////////////////////////////////////////////////////// 51 | 52 | gulp.task('styles', ['design-tokens'], () => 53 | gulp.src('src/styles/**/*.scss') 54 | .pipe(sass()) 55 | .pipe(gulp.dest(paths.output)) 56 | .pipe(livereload()) 57 | ) 58 | 59 | gulp.task('html', () => 60 | gulp.src('src/index.html') 61 | .pipe(gulp.dest(paths.output)) 62 | .pipe(livereload()) 63 | ) 64 | 65 | //////////////////////////////////////////////////////////////////// 66 | // Tasks - Watch 67 | //////////////////////////////////////////////////////////////////// 68 | 69 | gulp.task('watch', () => { 70 | livereload.listen({ 71 | port: 35729 72 | }) 73 | gulp.watch('design-tokens/**/*.json', ['styles']) 74 | gulp.watch('src/**/*.scss', ['styles']) 75 | gulp.watch('src/**/*.html', ['html']) 76 | }) 77 | 78 | gulp.task('dev', ['default'], () => { 79 | require('./server') 80 | gulp.start('watch') 81 | }) 82 | 83 | gulp.task('default', (done) => 84 | runSequence('clean', ['styleguide', 'styles', 'html'], done) 85 | ) --------------------------------------------------------------------------------