├── .eslintignore
├── site
├── README.md
├── next-env.d.ts
├── manifest.json
├── static
│ └── favicons
│ │ ├── favicon.ico
│ │ ├── favicon-16x16.png
│ │ ├── favicon-32x32.png
│ │ ├── apple-touch-icon.png
│ │ └── safari-pinned-tab.svg
├── next.config.js
├── tsconfig.json
├── .gitignore
├── pages
│ ├── _app.tsx
│ └── index.tsx
├── package.json
├── components
│ └── HtmlHead.tsx
└── build-manifest.js
├── babel.config.js
├── .gitignore
├── design-system
└── textfield
│ ├── CHANGELOG.md
│ ├── package.json
│ └── src
│ └── index.tsx
├── elemental-ui
├── radio
│ ├── package.json
│ └── src
│ │ └── index.tsx
├── reset
│ ├── package.json
│ └── src
│ │ └── index.tsx
├── button
│ ├── package.json
│ └── src
│ │ └── index.tsx
├── checkbox
│ ├── package.json
│ └── src
│ │ └── index.tsx
├── textarea
│ ├── package.json
│ └── src
│ │ └── index.tsx
└── textinput
│ ├── package.json
│ └── src
│ └── index.tsx
├── .changeset
├── README.md
└── config.js
├── tsconfig.json
├── TODO.md
├── .eslintrc.json
├── LICENSE
├── .circleci
└── config.yml
├── package.json
└── README.md
/.eslintignore:
--------------------------------------------------------------------------------
1 | node_modules
2 | dist
--------------------------------------------------------------------------------
/site/README.md:
--------------------------------------------------------------------------------
1 | # Design System Website
--------------------------------------------------------------------------------
/site/next-env.d.ts:
--------------------------------------------------------------------------------
1 | ///
2 | ///
3 |
--------------------------------------------------------------------------------
/site/manifest.json:
--------------------------------------------------------------------------------
1 | {
2 | "files": [
3 | "@elemental/textfield",
4 | "@unstyled/textfield"
5 | ]
6 | }
--------------------------------------------------------------------------------
/site/static/favicons/favicon.ico:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/design-systems-framework/design-system/HEAD/site/static/favicons/favicon.ico
--------------------------------------------------------------------------------
/site/static/favicons/favicon-16x16.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/design-systems-framework/design-system/HEAD/site/static/favicons/favicon-16x16.png
--------------------------------------------------------------------------------
/site/static/favicons/favicon-32x32.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/design-systems-framework/design-system/HEAD/site/static/favicons/favicon-32x32.png
--------------------------------------------------------------------------------
/site/static/favicons/apple-touch-icon.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/design-systems-framework/design-system/HEAD/site/static/favicons/apple-touch-icon.png
--------------------------------------------------------------------------------
/babel.config.js:
--------------------------------------------------------------------------------
1 | module.exports = {
2 | presets: [
3 | '@babel/preset-env',
4 | '@babel/preset-react',
5 | '@babel/preset-typescript',
6 | ],
7 | };
8 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | # See https://help.github.com/ignore-files/ for more about ignoring files.
2 |
3 | # dependencies
4 | node_modules
5 |
6 | # misc
7 | .DS_Store
8 | .env
9 | npm-debug.log*
10 | yarn-debug.log*
11 | yarn-error.log*
12 |
13 | dist/
14 |
--------------------------------------------------------------------------------
/design-system/textfield/CHANGELOG.md:
--------------------------------------------------------------------------------
1 | # @design-system/textfield
2 |
3 | ## 0.1.2
4 |
5 | ### Patch Changes
6 |
7 | - af4c756: Convert to TypeScript
8 |
9 | ## 0.1.1
10 |
11 | ### Patch Changes
12 |
13 | - 10564ac: Change to test release automation
14 |
--------------------------------------------------------------------------------
/site/next.config.js:
--------------------------------------------------------------------------------
1 | module.exports = {
2 | webpack(config, options) {
3 | config.module.rules.push({
4 | test: /\.+(js|jsx|ts|tsx)$/,
5 | use: options.defaultLoaders.babel,
6 | exclude: [/node_modules/],
7 | });
8 | return config;
9 | },
10 | };
11 |
--------------------------------------------------------------------------------
/site/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | // next creates a tsconfig even if there's one in a higher directory
3 | "extends": "../tsconfig.json",
4 | "compilerOptions": {
5 | // it also sets things so we need to do this
6 | "allowJs": false,
7 | "strict": true
8 | }
9 | }
10 |
--------------------------------------------------------------------------------
/site/.gitignore:
--------------------------------------------------------------------------------
1 | # See https://help.github.com/ignore-files/ for more about ignoring files.
2 |
3 | # dependencies
4 | node_modules
5 |
6 | # production
7 | /build
8 | /dist
9 | /.next
10 |
11 | # misc
12 | .DS_Store
13 | .env
14 | npm-debug.log*
15 | yarn-debug.log*
16 | yarn-error.log*
17 |
--------------------------------------------------------------------------------
/site/pages/_app.tsx:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 | import App, { Container } from 'next/app';
3 |
4 | export default class CustomApp extends App {
5 | render() {
6 | const { Component, pageProps } = this.props;
7 | return (
8 |
9 |
10 |
11 | );
12 | }
13 | }
14 |
--------------------------------------------------------------------------------
/site/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "@design-system/site",
3 | "version": "0.1.0",
4 | "private": true,
5 | "scripts": {
6 | "dev": "next",
7 | "build": "next build",
8 | "start": "next start"
9 | },
10 | "dependencies": {
11 | "glob": "^7.1.3",
12 | "glob-promise": "^3.4.0",
13 | "next": "^9.0.2",
14 | "react": "^16.8.9",
15 | "react-dom": "^16.8.3"
16 | }
17 | }
18 |
--------------------------------------------------------------------------------
/elemental-ui/radio/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "@elemental-ui/radio",
3 | "version": "0.0.1",
4 | "main": "dist/radio.cjs.js",
5 | "module": "dist/radio.esm.js",
6 | "author": "Thinkmill",
7 | "license": "MIT",
8 | "dependencies": {
9 | "@babel/runtime": "^7.4.3",
10 | "@emotion/core": "^10.0.7",
11 | "@types/react": "^16.8.23"
12 | },
13 | "peerDependencies": {
14 | "react": "^16.8.9"
15 | },
16 | "devDependencies": {
17 | "react": "^16.8.9"
18 | }
19 | }
20 |
--------------------------------------------------------------------------------
/elemental-ui/reset/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "@elemental-ui/reset",
3 | "version": "0.0.1",
4 | "main": "dist/reset.cjs.js",
5 | "module": "dist/reset.esm.js",
6 | "author": "Thinkmill",
7 | "license": "MIT",
8 | "dependencies": {
9 | "@babel/runtime": "^7.4.3",
10 | "@emotion/core": "^10.0.7",
11 | "@types/react": "^16.8.23"
12 | },
13 | "peerDependencies": {
14 | "react": "^16.8.9"
15 | },
16 | "devDependencies": {
17 | "react": "^16.8.9"
18 | }
19 | }
20 |
--------------------------------------------------------------------------------
/elemental-ui/button/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "@elemental-ui/button",
3 | "version": "0.0.1",
4 | "main": "dist/button.cjs.js",
5 | "module": "dist/button.esm.js",
6 | "author": "Thinkmill",
7 | "license": "MIT",
8 | "dependencies": {
9 | "@babel/runtime": "^7.4.3",
10 | "@emotion/core": "^10.0.7",
11 | "@types/react": "^16.8.23"
12 | },
13 | "peerDependencies": {
14 | "react": "^16.8.9"
15 | },
16 | "devDependencies": {
17 | "react": "^16.8.9"
18 | }
19 | }
20 |
--------------------------------------------------------------------------------
/elemental-ui/checkbox/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "@elemental-ui/checkbox",
3 | "version": "0.0.1",
4 | "main": "dist/checkbox.cjs.js",
5 | "module": "dist/checkbox.esm.js",
6 | "author": "Thinkmill",
7 | "license": "MIT",
8 | "dependencies": {
9 | "@babel/runtime": "^7.4.3",
10 | "@emotion/core": "^10.0.7",
11 | "@types/react": "^16.8.23"
12 | },
13 | "peerDependencies": {
14 | "react": "^16.8.9"
15 | },
16 | "devDependencies": {
17 | "react": "^16.8.9"
18 | }
19 | }
20 |
--------------------------------------------------------------------------------
/elemental-ui/textarea/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "@elemental-ui/textarea",
3 | "version": "0.0.1",
4 | "main": "dist/textarea.cjs.js",
5 | "module": "dist/textarea.esm.js",
6 | "author": "Thinkmill",
7 | "license": "MIT",
8 | "dependencies": {
9 | "@babel/runtime": "^7.4.3",
10 | "@emotion/core": "^10.0.7",
11 | "@types/react": "^16.8.23"
12 | },
13 | "peerDependencies": {
14 | "react": "^16.8.9"
15 | },
16 | "devDependencies": {
17 | "react": "^16.8.9"
18 | }
19 | }
20 |
--------------------------------------------------------------------------------
/elemental-ui/textinput/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "@elemental-ui/textinput",
3 | "version": "0.0.1",
4 | "main": "dist/textinput.cjs.js",
5 | "module": "dist/textinput.esm.js",
6 | "author": "Thinkmill",
7 | "license": "MIT",
8 | "dependencies": {
9 | "@babel/runtime": "^7.4.3",
10 | "@emotion/core": "^10.0.7",
11 | "@types/react": "^16.8.23"
12 | },
13 | "peerDependencies": {
14 | "react": "^16.8.9"
15 | },
16 | "devDependencies": {
17 | "react": "^16.8.9"
18 | }
19 | }
20 |
--------------------------------------------------------------------------------
/design-system/textfield/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "@design-system/textfield",
3 | "version": "0.1.2",
4 | "main": "dist/textfield.cjs.js",
5 | "module": "dist/textfield.esm.js",
6 | "license": "MIT",
7 | "dependencies": {
8 | "@babel/runtime": "^7.4.3",
9 | "@emotion/core": "^10.0.7",
10 | "@types/react": "^16.8.23"
11 | },
12 | "peerDependencies": {
13 | "react": "^16.8.9"
14 | },
15 | "devDependencies": {
16 | "react": "^16.8.9",
17 | "react-dom": "^16.8.3"
18 | }
19 | }
20 |
--------------------------------------------------------------------------------
/.changeset/README.md:
--------------------------------------------------------------------------------
1 | # Changesets
2 |
3 | Hello and welcome! This folder has been automatically generated by `@changesets/cli`, a build tool that works with mono-repos or single package repos to help you verion and release your code. You can find the full documentation for it [in our repository](https://github.com/changesets/changesets)
4 |
5 | We have a quick list of common questions to get you started engaging with this project in [our documentation](https://github.com/changesets/changesets/blob/master/docs/common-questions.md)
6 |
--------------------------------------------------------------------------------
/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "compilerOptions": {
3 | "target": "es5",
4 | "lib": ["dom", "dom.iterable", "esnext"],
5 | "skipLibCheck": true,
6 | "forceConsistentCasingInFileNames": true,
7 | "noEmit": true,
8 | "esModuleInterop": true,
9 | "module": "esnext",
10 | "moduleResolution": "node",
11 | "resolveJsonModule": true,
12 | "isolatedModules": true,
13 | "jsx": "preserve"
14 | },
15 | "exclude": ["node_modules"],
16 | "include": ["./site/next-env.d.ts", "**/*.ts", "**/*.tsx"]
17 | }
18 |
--------------------------------------------------------------------------------
/TODO.md:
--------------------------------------------------------------------------------
1 | # design-system
2 |
3 | ## TODO
4 |
5 | ### Infra:
6 | - [ ] Setup CI
7 | - [ ] Setup Netlify and integrate with CI
8 | - [ ] Setup build step for non website workspaces.
9 | - [ ] Integrate with change-sets
10 | - [ ] Setup initial dev workflow with Next.js
11 | - [ ] Setup dev loop external of Next.js site*
12 |
13 | ### Unstyled Components:
14 | - [ ] Button
15 | - [ ] Textfield
16 | - [ ] ???
17 | ### Elemental Components:
18 | - [ ] Button
19 | - [ ] Textfield
20 |
21 | \* = probably not high priority till we decide to make this thing public)
22 |
--------------------------------------------------------------------------------
/.eslintrc.json:
--------------------------------------------------------------------------------
1 | {
2 | "extends": ["standard", "standard-react", "prettier", "prettier/react"],
3 | "plugins": ["prettier"],
4 | "parser": "babel-eslint",
5 | "rules": {
6 | "prettier/prettier": "error",
7 | "react/prop-types": 0,
8 | "react/no-unused-prop-types": 0,
9 | "standard/computed-property-even-spacing": 0,
10 | "no-template-curly-in-string": 0,
11 | "camelcase": 0,
12 | "import/no-duplicates": 0,
13 | "import/no-unresolved": 2
14 | },
15 | "env": {
16 | "browser": true
17 | },
18 | "overrides": [
19 | {
20 | "files": ["*.test.js", "**/__tests__/**"],
21 | "env": {
22 | "jest": true
23 | }
24 | }
25 | ]
26 | }
27 |
--------------------------------------------------------------------------------
/site/components/HtmlHead.tsx:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 | import Head from 'next/head';
3 |
4 | type Props = {
5 | title: string;
6 | children?: React.ReactNode;
7 | };
8 |
9 | export default ({ title = 'Design System™', children }: Props) => (
10 |
11 | {title}
12 |
18 |
24 |
25 | {children}
26 |
27 | );
28 |
--------------------------------------------------------------------------------
/elemental-ui/reset/src/index.tsx:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 | import { Global, css } from '@emotion/core';
3 |
4 | // TODO: Pull these font stacks from a theme package
5 |
6 | const resetCSS = css`
7 | html {
8 | font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto,
9 | 'Helvetica Neue', Arial, 'Noto Sans', sans-serif, 'Apple Color Emoji',
10 | 'Segoe UI Emoji', 'Segoe UI Symbol', 'Noto Color Emoji';
11 | line-height: 1.5;
12 | }
13 | pre,
14 | code,
15 | kbd,
16 | samp {
17 | font-family: Menlo, Monaco, Consolas, 'Liberation Mono', 'Courier New',
18 | monospace;
19 | }
20 | `;
21 |
22 | export default function Reset() {
23 | return ;
24 | }
25 |
--------------------------------------------------------------------------------
/site/build-manifest.js:
--------------------------------------------------------------------------------
1 | const { workspaces } = require('../package.json');
2 | const fs = require('fs');
3 | const path = require('path');
4 | const glob = require('glob-promise');
5 |
6 | (async () => {
7 | try {
8 | const files = await Promise.all(
9 | workspaces.map(async key => {
10 | const globPath = path.resolve(__dirname, `../${key}`);
11 | if (key === 'site') return;
12 | const filePaths = await glob(globPath);
13 | return filePaths.map(filePath => {
14 | const { name } = require(path.resolve(filePath, './package.json'));
15 | return name;
16 | });
17 | })
18 | );
19 | const formattedFiles = files
20 | .reduce((acc, curr) => acc.concat(curr), [])
21 | .filter(f => f);
22 | fs.writeFileSync(
23 | 'manifest.json',
24 | JSON.stringify({ files: formattedFiles }, null, 1)
25 | );
26 | } catch (e) {
27 | console.error(e);
28 | }
29 | })();
30 |
--------------------------------------------------------------------------------
/site/pages/index.tsx:
--------------------------------------------------------------------------------
1 | import * as React from 'react';
2 | import HtmlHead from '../components/HtmlHead';
3 | import Reset from '@elemental-ui/reset';
4 | import Button from '@elemental-ui/button';
5 | import Checkbox from '@elemental-ui/checkbox';
6 | import Radio from '@elemental-ui/radio';
7 | import Textarea from '@elemental-ui/textarea';
8 | import TextInput from '@elemental-ui/textinput';
9 |
10 | const Home = () => (
11 | <>
12 |
13 |
14 | Design System™
15 |
16 | Button
17 | Click Me
18 | Checkbox
19 |
20 | Check Me
21 | Radio
22 |
23 | Check Me
24 | Textarea
25 |
26 | Text Input
27 |
28 | >
29 | );
30 |
31 | export default Home;
32 |
--------------------------------------------------------------------------------
/elemental-ui/textinput/src/index.tsx:
--------------------------------------------------------------------------------
1 | /** @jsx jsx */
2 | import { jsx } from '@emotion/core';
3 |
4 | const defaultInputStyles = (state: Record) => ({
5 | display: 'inline-block',
6 | });
7 |
8 | const defaults: Record = {
9 | Input: {
10 | component: (props: Record) => ,
11 | styles: defaultInputStyles,
12 | },
13 | };
14 |
15 | function getOverrides(key: string, overrides: Record = {}) {
16 | if (!overrides[key]) {
17 | return defaults[key];
18 | } else {
19 | return {
20 | ...defaults[key],
21 | ...overrides[key],
22 | };
23 | }
24 | }
25 |
26 | export interface TextInputProps {
27 | overrides?: Record;
28 | }
29 |
30 | export default function Input({ overrides, ...props }: TextInputProps) {
31 | const { styles, attributes, component: InputComponent } = getOverrides(
32 | 'Input',
33 | overrides
34 | );
35 | return ;
36 | }
37 |
--------------------------------------------------------------------------------
/elemental-ui/textarea/src/index.tsx:
--------------------------------------------------------------------------------
1 | /** @jsx jsx */
2 | import { jsx } from '@emotion/core';
3 |
4 | const defaultInputStyles = (state: Record) => ({
5 | display: 'inline-block',
6 | });
7 |
8 | const defaults: Record = {
9 | Input: {
10 | component: (props: Record) => (
11 |
12 | ),
13 | styles: defaultInputStyles,
14 | },
15 | };
16 |
17 | function getOverrides(key: string, overrides: Record = {}) {
18 | if (!overrides[key]) {
19 | return defaults[key];
20 | } else {
21 | return {
22 | ...defaults[key],
23 | ...overrides[key],
24 | };
25 | }
26 | }
27 |
28 | export interface TextAreaProps {
29 | overrides?: Record;
30 | }
31 |
32 | export default function Input({ overrides, ...props }: TextAreaProps) {
33 | const { styles, attributes, component: InputComponent } = getOverrides(
34 | 'Input',
35 | overrides
36 | );
37 | return ;
38 | }
39 |
--------------------------------------------------------------------------------
/elemental-ui/button/src/index.tsx:
--------------------------------------------------------------------------------
1 | /** @jsx jsx */
2 | import { jsx } from '@emotion/core';
3 |
4 | const defaultInputStyles = (state: Record) => ({
5 | display: 'inline-block',
6 | });
7 |
8 | const defaults: Record = {
9 | Input: {
10 | component: (props: Record) => ,
11 | styles: defaultInputStyles,
12 | },
13 | };
14 |
15 | function getOverrides(key: string, overrides: Record = {}) {
16 | if (!overrides[key]) {
17 | return defaults[key];
18 | } else {
19 | return {
20 | ...defaults[key],
21 | ...overrides[key],
22 | };
23 | }
24 | }
25 |
26 | export interface ButtonProps {
27 | overrides?: Record;
28 | }
29 |
30 | const Button: React.ComponentType = function Button({ overrides, ...props }: ButtonProps) {
31 | const { styles, attributes, component: InputComponent } = getOverrides(
32 | 'Input',
33 | overrides
34 | );
35 | return ;
36 | }
37 |
38 | export default Button
39 |
--------------------------------------------------------------------------------
/elemental-ui/radio/src/index.tsx:
--------------------------------------------------------------------------------
1 | /** @jsx jsx */
2 | import { jsx } from '@emotion/core';
3 |
4 | const defaultInputStyles = (state: Record) => ({
5 | display: 'inline-block',
6 | });
7 |
8 | const defaults: Record = {
9 | Input: {
10 | component: (props: Record) => (
11 |
12 | ),
13 | styles: defaultInputStyles,
14 | },
15 | };
16 |
17 | function getOverrides(key: string, overrides: Record = {}) {
18 | if (!overrides[key]) {
19 | return defaults[key];
20 | } else {
21 | return {
22 | ...defaults[key],
23 | ...overrides[key],
24 | };
25 | }
26 | }
27 |
28 | export interface TextAreaProps extends React.AllHTMLAttributes{
29 | overrides?: Record;
30 | }
31 |
32 | export default function Input({ overrides, ...props }: TextAreaProps) {
33 | const { styles, attributes, component: InputComponent } = getOverrides(
34 | 'Input',
35 | overrides
36 | );
37 | return ;
38 | }
39 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | MIT License
2 |
3 | Copyright (c) 2018 Thinkmill Pty Ltd
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
22 |
--------------------------------------------------------------------------------
/elemental-ui/checkbox/src/index.tsx:
--------------------------------------------------------------------------------
1 | /** @jsx jsx */
2 | import { jsx } from '@emotion/core';
3 |
4 | const defaultInputStyles = (state: Record) => ({
5 | display: 'inline-block',
6 | });
7 |
8 | const defaults: Record = {
9 | Input: {
10 | component: (props: Record) => (
11 |
12 | ),
13 | styles: defaultInputStyles,
14 | },
15 | };
16 |
17 | function getOverrides(key: string, overrides: Record = {}) {
18 | if (!overrides[key]) {
19 | return defaults[key];
20 | } else {
21 | return {
22 | ...defaults[key],
23 | ...overrides[key],
24 | };
25 | }
26 | }
27 |
28 | export interface TextAreaProps extends React.AllHTMLAttributes{
29 | overrides?: Record;
30 | }
31 | const Input: React.ComponentType = function Input({ overrides, ...props }: TextAreaProps) {
32 | const { styles, attributes, component: InputComponent } = getOverrides(
33 | 'Input',
34 | overrides
35 | );
36 | return ;
37 | }
38 |
39 | export default Input
--------------------------------------------------------------------------------
/.circleci/config.yml:
--------------------------------------------------------------------------------
1 | version: 2
2 | jobs:
3 | lint:
4 | docker:
5 | - image: circleci/node:10.6.0
6 | working_directory: ~/repo
7 | steps:
8 | - checkout
9 | - restore_cache:
10 | keys:
11 | - v2-dependencies-{{ checksum "yarn.lock" }}
12 | # fallback to using the latest cache if no exact match is found
13 | - v2-dependencies-
14 | - run:
15 | name: Install
16 | command: yarn install --pure-lockfile
17 | - run:
18 | name: 'ESLint'
19 | command: yarn eslint .
20 | types:
21 | docker:
22 | - image: circleci/node:10.6.0
23 | working_directory: ~/repo
24 | steps:
25 | - checkout
26 | - restore_cache:
27 | keys:
28 | - v2-dependencies-{{ checksum "yarn.lock" }}
29 | # fallback to using the latest cache if no exact match is found
30 | - v2-dependencies-
31 | - run:
32 | name: Install
33 | command: yarn install --pure-lockfile
34 | - run:
35 | name: 'Type Checking'
36 | command: yarn tsc
37 |
38 | release:
39 | docker:
40 | - image: circleci/node:10.6.0
41 | working_directory: ~/repo
42 | steps:
43 | - checkout
44 | - restore_cache:
45 | keys:
46 | - v2-dependencies-{{ checksum "yarn.lock" }}
47 | # fallback to using the latest cache if no exact match is found
48 | - v2-dependencies-
49 | - run:
50 | name: Install
51 | command: yarn install --pure-lockfile
52 | - run:
53 | name: 'Release'
54 | command: yarn experimental-changesets-auto-release
55 |
56 | workflows:
57 | version: 2
58 | test:
59 | jobs:
60 | - lint
61 | - types
62 | release:
63 | jobs:
64 | - release:
65 | filters:
66 | branches:
67 | only: master
68 |
--------------------------------------------------------------------------------
/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "@design-system/monorepo",
3 | "version": "0.1.0",
4 | "private": true,
5 | "workspaces": [
6 | "elemental-ui/*",
7 | "design-system/*",
8 | "site"
9 | ],
10 | "dependencies": {
11 | "@babel/core": "^7.4.5",
12 | "@babel/preset-env": "^7.4.5",
13 | "@babel/preset-react": "^7.0.0",
14 | "@babel/preset-typescript": "^7.3.3",
15 | "@babel/runtime": "^7.4.3",
16 | "@changesets/cli": "^1.2.0",
17 | "@emotion/core": "^10.0.7",
18 | "@mitchellhamilton/experimental-changesets-auto-release": "^0.0.2",
19 | "babel-eslint": "^10.0.2",
20 | "bolt-check": "^0.3.0",
21 | "eslint": "^5.14.1",
22 | "eslint-config-prettier": "^6.0.0",
23 | "eslint-config-standard": "^12.0.0",
24 | "eslint-config-standard-react": "^7.0.2",
25 | "eslint-plugin-import": "^2.18.0",
26 | "eslint-plugin-node": "^9.1.0",
27 | "eslint-plugin-prettier": "^3.1.0",
28 | "eslint-plugin-promise": "^4.2.1",
29 | "eslint-plugin-react": "^7.14.2",
30 | "eslint-plugin-standard": "^4.0.0",
31 | "glob": "^7.1.3",
32 | "glob-promise": "^3.4.0",
33 | "next": "^9.0.2",
34 | "preconstruct": "^0.0.82",
35 | "prettier": "^1.18.2",
36 | "react": "^16.8.9",
37 | "react-dom": "^16.8.3",
38 | "typescript": "^3.5.3",
39 | "@types/react": "^16.8.23"
40 | },
41 | "browserslist": [
42 | ">0.2%",
43 | "not dead",
44 | "not ie <= 11",
45 | "not op_mini all"
46 | ],
47 | "prettier": {
48 | "trailingComma": "es5",
49 | "singleQuote": true
50 | },
51 | "scripts": {
52 | "watch": "preconstruct watch",
53 | "build": "preconstruct build",
54 | "version-packages": "changeset bump",
55 | "release": "yarn build && changeset release",
56 | "start": "cd ./site && yarn dev",
57 | "postinstall": "preconstruct dev && bolt-check",
58 | "lint": "eslint .",
59 | "lint:fix": "yarn lint --fix"
60 | },
61 | "preconstruct": {
62 | "packages": [
63 | "elemental-ui/*",
64 | "design-system/*"
65 | ]
66 | }
67 | }
68 |
--------------------------------------------------------------------------------
/design-system/textfield/src/index.tsx:
--------------------------------------------------------------------------------
1 | /** @jsx jsx */
2 |
3 | import { useState, useRef } from 'react';
4 | import { jsx, CSSObject } from '@emotion/core';
5 |
6 | type BaseProps = {
7 | isDisabled: boolean;
8 | isReadOnly: boolean;
9 | isRequired: boolean;
10 | isInvalid: boolean;
11 | };
12 |
13 | type StyleProps = BaseProps & {
14 | isFocused: boolean;
15 | } & React.InputHTMLAttributes;
16 |
17 | type StyleFunc = (props: StyleProps) => CSSObject;
18 |
19 | const inputWrapperStyles: StyleFunc = props => ({
20 | display: 'flex',
21 | background: 'white',
22 | flex: '1 0 auto',
23 | boxSizing: 'border-box',
24 | });
25 | const inputStyles: StyleFunc = props => ({
26 | width: '100%',
27 | });
28 |
29 | type StylesProp = {
30 | [K in keyof TypeOfDefaultStyles]?: (
31 | defaultStyles: CSSObject,
32 | props: StyleProps
33 | ) => CSSObject;
34 | };
35 |
36 | const defaultStyles = {
37 | input: inputStyles,
38 | inputWrapper: inputWrapperStyles,
39 | } as const;
40 |
41 | type Props = Partial &
42 | React.InputHTMLAttributes & {
43 | styles?: StylesProp;
44 | };
45 |
46 | const Textfield = ({
47 | styles,
48 | isDisabled = false,
49 | isReadOnly = false,
50 | isRequired = false,
51 | isInvalid = false,
52 | ...rest
53 | }: Props) => {
54 | const [isFocused, setFocused] = useState(false);
55 | const inputEl = useRef(null);
56 |
57 | const getStyles = (
58 | key: keyof typeof defaultStyles,
59 | styleProps: StyleProps
60 | ) => {
61 | // If there's an existing styles prop
62 | // check for styles[key](theme[key](styleProps))
63 | // otherwise just return theme[key](styleProps);
64 | const defaultStyle = defaultStyles[key](styleProps);
65 |
66 | return styles && styles[key]
67 | ? styles[key](defaultStyle, styleProps)
68 | : defaultStyle;
69 | };
70 |
71 | const handleOnFocus = (event: React.FocusEvent) => {
72 | setFocused(true);
73 | if (rest.onFocus) {
74 | rest.onFocus(event);
75 | }
76 | };
77 |
78 | const handleOnBlur = (event: React.FocusEvent) => {
79 | setFocused(false);
80 | if (rest.onBlur) {
81 | rest.onBlur(event);
82 | }
83 | };
84 |
85 | const styleProps = {
86 | isDisabled,
87 | isFocused,
88 | isReadOnly,
89 | isRequired,
90 | isInvalid,
91 | ...rest,
92 | };
93 |
94 | return (
95 |
96 |
106 |
107 | );
108 | };
109 |
110 | export default Textfield;
111 |
--------------------------------------------------------------------------------
/site/static/favicons/safari-pinned-tab.svg:
--------------------------------------------------------------------------------
1 |
2 |
4 |
7 |
8 | Created by potrace 1.11, written by Peter Selinger 2001-2013
9 |
10 |
12 |
32 |
38 |
46 |
47 |
48 |
--------------------------------------------------------------------------------
/.changeset/config.js:
--------------------------------------------------------------------------------
1 | /*
2 | Hey, welcome to the changeset config! This file has been generated
3 | for you with the default configs we use, and some comments around
4 | what options mean, so that it's easy to customise your workflow.
5 |
6 | You should update this as you need to craft your workflow.
7 |
8 | Config provided by a CI command takes precedence over the contents of this file.
9 |
10 | If a config option isn't present here, we will fall back to the defaults.
11 | */
12 |
13 | const changesetOptions = {
14 | // If true, we will automatically commit the changeset when the command is run
15 | commit: false,
16 | };
17 |
18 | // This function takes information about a changeset to generate an entry for it in your
19 | // changelog. We provide the full changeset object as well as the version.
20 | // It may be a good idea to replace the commit hash with a link to the commit.
21 |
22 | /* the default shape is:
23 | ### Bump Type
24 |
25 | - GIT_HASH: A summary message you wrote, indented?
26 | */
27 |
28 | const getReleaseLine = async (changeset, type) => {
29 | const [firstLine, ...futureLines] = changeset.summary
30 | .split('\n')
31 | .map(l => l.trimRight());
32 |
33 | return `- ${changeset.commit}: ${firstLine}\n${futureLines
34 | .map(l => ` ${l}`)
35 | .join('\n')}`;
36 | };
37 |
38 | // This function takes information about what dependencies we are updating in the package.
39 | // It provides an array of related changesets, as well as the dependencies updated.
40 |
41 | /*
42 | - Updated dependencies: [ABCDEFG]:
43 | - Updated dependencies: [HIJKLMN]:
44 | - dependencyA@1.0.1
45 | - dependencyb@1.2.0
46 | */
47 | const getDependencyReleaseLine = async (changesets, dependenciesUpdated) => {
48 | if (dependenciesUpdated.length === 0) return '';
49 |
50 | const changesetLinks = changesets.map(
51 | changeset => `- Updated dependencies [${changeset.commit}]:`
52 | );
53 |
54 | const updatedDepenenciesList = dependenciesUpdated.map(
55 | dependency => ` - ${dependency.name}@${dependency.version}`
56 | );
57 |
58 | return [...changesetLinks, ...updatedDepenenciesList].join('\n');
59 | };
60 |
61 | const versionOptions = {
62 | // If true, we will automatically commit the version updating when the command is run
63 | commit: false,
64 | // Adds a skipCI flag to the commit - only valid if `commit` is also true.
65 | skipCI: false,
66 | // Do not modify the `changelog.md` files for packages that are updated
67 | updateChangelog: true,
68 | // A function that returns a string. It takes in options about a change. This allows you to customise your changelog entries
69 | getReleaseLine,
70 | // A function that returns a string. It takes in options about when a pacakge is updated because
71 | getDependencyReleaseLine,
72 | // An array of arrays that defines packages that are linked.
73 | // Linked packages are packages that should be at the same version when they're released.
74 | // If you've used Lerna to version packages before, this is very similar.
75 | linked: [[]],
76 | };
77 |
78 | const publishOptions = {
79 | // This sets whether unpublished packages are public by default. We err on the side of caution here.
80 | public: true,
81 | };
82 |
83 | module.exports = {
84 | versionOptions,
85 | changesetOptions,
86 | publishOptions,
87 | };
88 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # Design Systems Framework: Raison d’être
2 |
3 | ## Mission Statement
4 |
5 | To make building, maintaining and distributing your design-system simpler.
6 |
7 | ## The Problem
8 |
9 | Design systems, help us efficiently apply and distribute our design opinions throughout our products. This efficiency helps us create user experiences that are more consistent across products, which lends to opportunities for cohesive interoperability. (Bitbucket and Jira for example or MacOS and iOS)
10 |
11 | A substantial amount of effort in setting up design-systems is spent implementing and (usually) repeating functionality around:
12 |
13 | - Accessibility standards
14 | - Interaction and state management
15 | - Platform dependent best practices
16 | - Compositional API
17 |
18 | These are often times the same or very similar across most design-systems.
19 |
20 | ## Design Systems as a composition
21 |
22 | The conventional way of looking at a design-system is a library of Components, associated documentation and patterns. However we can also think of them as a composition of design / thematic options over encapsulated functionality.
23 |
24 | ```
25 | ds = f(t)
26 | ```
27 |
28 | Our hypothesis is that by providing building blocks that represent `f` , we empower design-system authors to focus more of their energy on the bespoke aspects of their design-system, and not on the boiler-plate.
29 |
30 | ## Shared tooling and not just components
31 |
32 | Best practices around building and maintaining design systems don’t just extend to the creation of components, but also to things like:
33 |
34 | - Build processes
35 | - Versioning and Publishing workflows
36 | - Documentation artifacts - website - technical documentation (prop-types, tokens etc) - conceptual documentation - usage documentation (upgrade guides, how-too) - live examples - code snippets
37 | - Documentation best practices
38 | - Development environments
39 |
40 | The aim of DSF is not just to make _*building*_ your components easier, but also building and maintaining your _*design-system*_. This means providing:
41 |
42 | - Build tooling and guidelines
43 | - Documentation tooling and guidelines
44 | - Components
45 | - Utilities for _*building*_ components
46 | - Versioning and Publishing tools.
47 |
48 | Not every design system should be built in the same way, but where possible we want to empower design-system authors by sharing tools that make building design-systems simpler and faster.
49 |
50 | # Design Systems Framework Patterns
51 |
52 | ## RenderProps
53 |
54 | ## Components API
55 |
56 | ## Styles API
57 |
58 | ## Working on Design Systems Framework inside another project
59 |
60 | To iterate on DSF while working on another project without having to publish DSF after every change, you can use [`link-monorepos-badly`](https://github.com/mitchellhamilton/link-monorepos-badly).
61 |
62 | Make sure you've done an install in DSF and your project.
63 |
64 | ```bash
65 | # From your clone of the DSF repo
66 | yarn
67 | cd ../another-project
68 | # If you're using Yarn Workspaces in your project
69 | yarn
70 | # If you're using Bolt in your project
71 | bolt
72 | ```
73 |
74 | Install `link-monorepos-badly` globally
75 |
76 | ```bash
77 | yarn global add link-monorepos-badly
78 | ```
79 |
80 | Now you can use `link-monorepos-badly` to link packages into your project
81 |
82 | ```bash
83 | link-monorepos-badly link ../design-system
84 | ```
85 |
86 | When you're done linking, you can unlink and reinstall the packages
87 |
88 | ```bash
89 | link-monorepos-badly unlink ../design-system
90 | # If you're using Yarn Workspaces in your project
91 | yarn
92 | # If you're using Bolt in your project
93 | bolt
94 | ```
95 |
96 | Once a new release of DSF has happened, you can upgrade all the DSF packages with the `upgrade` command
97 |
98 | ```bash
99 | link-monorepos-badly upgrade ../design-system
100 | # If you're using Yarn Workspaces in your project
101 | yarn
102 | # If you're using Bolt in your project
103 | bolt
104 | ```
105 |
--------------------------------------------------------------------------------