├── .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 | )
--------------------------------------------------------------------------------