├── .gitignore ├── LICENSE ├── README.md ├── org.md └── package.json /.gitignore: -------------------------------------------------------------------------------- 1 | 2 | # Created by https://www.gitignore.io/api/node,macos,windows 3 | 4 | ### macOS ### 5 | # General 6 | .DS_Store 7 | .AppleDouble 8 | .LSOverride 9 | 10 | # Icon must end with two \r 11 | Icon 12 | 13 | # Thumbnails 14 | ._* 15 | 16 | # Files that might appear in the root of a volume 17 | .DocumentRevisions-V100 18 | .fseventsd 19 | .Spotlight-V100 20 | .TemporaryItems 21 | .Trashes 22 | .VolumeIcon.icns 23 | .com.apple.timemachine.donotpresent 24 | 25 | # Directories potentially created on remote AFP share 26 | .AppleDB 27 | .AppleDesktop 28 | Network Trash Folder 29 | Temporary Items 30 | .apdisk 31 | 32 | ### Node ### 33 | # Logs 34 | logs 35 | *.log 36 | npm-debug.log* 37 | yarn-debug.log* 38 | yarn-error.log* 39 | 40 | # Runtime data 41 | pids 42 | *.pid 43 | *.seed 44 | *.pid.lock 45 | 46 | # Directory for instrumented libs generated by jscoverage/JSCover 47 | lib-cov 48 | 49 | # Coverage directory used by tools like istanbul 50 | coverage 51 | 52 | # nyc test coverage 53 | .nyc_output 54 | 55 | # Grunt intermediate storage (http://gruntjs.com/creating-plugins#storing-task-files) 56 | .grunt 57 | 58 | # Bower dependency directory (https://bower.io/) 59 | bower_components 60 | 61 | # node-waf configuration 62 | .lock-wscript 63 | 64 | # Compiled binary addons (https://nodejs.org/api/addons.html) 65 | build/Release 66 | 67 | # Dependency directories 68 | node_modules/ 69 | jspm_packages/ 70 | 71 | # TypeScript v1 declaration files 72 | typings/ 73 | 74 | # Optional npm cache directory 75 | .npm 76 | 77 | # Optional eslint cache 78 | .eslintcache 79 | 80 | # Optional REPL history 81 | .node_repl_history 82 | 83 | # Output of 'npm pack' 84 | *.tgz 85 | 86 | # Yarn Integrity file 87 | .yarn-integrity 88 | 89 | # dotenv environment variables file 90 | .env 91 | 92 | # parcel-bundler cache (https://parceljs.org/) 93 | .cache 94 | 95 | # next.js build output 96 | .next 97 | 98 | # nuxt.js build output 99 | .nuxt 100 | 101 | # vuepress build output 102 | .vuepress/dist 103 | 104 | # Serverless directories 105 | .serverless 106 | 107 | ### Windows ### 108 | # Windows thumbnail cache files 109 | Thumbs.db 110 | ehthumbs.db 111 | ehthumbs_vista.db 112 | 113 | # Dump file 114 | *.stackdump 115 | 116 | # Folder config file 117 | [Dd]esktop.ini 118 | 119 | # Recycle Bin used on file shares 120 | $RECYCLE.BIN/ 121 | 122 | # Windows Installer files 123 | *.cab 124 | *.msi 125 | *.msix 126 | *.msm 127 | *.msp 128 | 129 | # Windows shortcuts 130 | *.lnk 131 | 132 | 133 | # End of https://www.gitignore.io/api/node,macos,windows 134 | *.sublime-project 135 | *.sublime-workspace 136 | package-lock.json 137 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2019 Thinkmill 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 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Thinkmill Design System Style Guide 2 | 3 | Important Note: This style guide is currently very WIP 4 | 5 | --- 6 | 7 | ## What is this style guide? 8 | 9 | This style guide documents the standards for building and maintaining design systems we follow at Thinkmill along with explaining the reasoning for our decisions and tooling. 10 | 11 | This style guide is intended to be a living representation of how Thinkmill works with design systems. Over time, the recommendations will change as our tools and workflows evolve. While the guide is designed holistically, the tools and decisions in this guide can be used independently of each other. 12 | 13 | ## Who is this style-guide for? 14 | 15 | This style-guide is intended to be opinionated, and focused on the kinds of work that Thinkmill does. Many decision inherently have trade-offs and the trade-offs made in this style-guide might not be the right ones for every company. We document these decisions fastidiously, and encourage you to use the bits that make sense for you. 16 | 17 | ## Concepts 18 | 19 | > What is a design system? Purpose, Goals, Reasoning. 20 | 21 | "A Design System is an artefact of the culture and collaboration in your company" -- Dom 22 | 23 | > Need to either cover or link out to methodolgy here, see [Dom's first notes on this](https://github.com/Thinkmill/design-system/blob/master/org.md) 24 | 25 | ### Terminology 26 | 27 | (all wip and in need of further discussion) 28 | 29 | - Design Language 30 | 31 | > The collection of design decisions that represent a company, brand or product. Usually includes colour, typography, spacing, language and tone of voice, illustrations and iconography, visual style, and patterns of applying all of these to reference designs. 32 | 33 | - Design System 34 | 35 | > The composition of components, patterns and processes that is consumable, documented, published to be able to be reusable and scalable in a business domain 36 | 37 | - Design Tokens 38 | 39 | > Implementation agnostic variables that describe the subset of values core to a design system. 40 | 41 | - Theme 42 | 43 | > A customisable subset of design decisions that expresses sweeping style changes through the system. 44 | 45 | - Packs 46 | 47 | > A cluster of design tokens grouped according to how they should be used. See [Packs](#Packs) 48 | 49 | - Packages 50 | 51 | > A collection of one or more components or utilities, conceptually identifiable as a concern of the design system, documented and published to a package registry. 52 | 53 | - Components 54 | 55 | > Components encapsulate functionality that renders a `view` with `styles` based on a `state`. 56 | > See [Components](#Components) 57 | 58 | - State 59 | 60 | > The combination of component that affect the appearance or behaviour of the 61 | 62 | - Controllable State 63 | 64 | > This is an important concept regarding how state can be optionally provided to a component, along with a callback that is invoked when the state should change. The fallback behaviour is for the component to manage the state and default callback behaviour internally. 65 | 66 | - Switches 67 | 68 | > Props that can change the appearance and/or behaviour of a component. Often selected from a set of possible values. Examples include appearance or color of a button, first day of the week in a calendar, etc. 69 | 70 | # Design Tokens 71 | 72 | ## Global Tokens 73 | 74 | ## Packs 75 | 76 | # Theming 77 | 78 | # Components 79 | 80 | > NOTE: Here we describe developing React components for a design system. The principles are largely translatable to React Native projects as well, but other frameworks and technologies are out of scope for our style guide at this time. 81 | 82 | > TODO: Review [React Patterns](https://reactpatterns.com) for inspiration - this does a good job of presenting various technical approaches you can take in React, and we can learn from the way it is organised and presented! 83 | 84 | Components encapsulate functionality that renders a `view` with `styles` based on a `state`. 85 | 86 | `(state) => ({ styles, view })` 87 | 88 | We also recognise functional building blocks and controllers that are used by components to manage state, side effects and other concerns. 89 | 90 | ## Package Structure 91 | 92 | > TODO: this needs to go hand-in-hand with some more depth around how documentation and examples are developed and published to make sense. 93 | 94 | ``` 95 | - docs/ 96 | - examples/ 97 | - src/ 98 | - index.js 99 | - styles.js 100 | - tests/ 101 | - package.json 102 | ``` 103 | 104 | ## Types 105 | 106 | Use [TypeScript](https://www.typescriptlang.org). 107 | 108 | Among other things, it'll help you easily generate [Documentation](#Documentation) for your component APIs. 109 | 110 | ## API Design 111 | 112 | ## State Management 113 | 114 | > needs content from @jedwatson and @simonswiss. 115 | 116 | > There's definitely stuff here from treatise on state we need to clarify 117 | 118 | > But beyond that we should also have stuff around the different kinds of UI state (Mike R.) 119 | 120 | ## Styles 121 | 122 | Use [emotion](https://emotion.sh/) with the [css prop](https://emotion.sh/docs/css-prop). 123 | 124 | Specify styles in a function that is invoked with the current state of the component and design tokens, and return a css object: 125 | 126 | ```js 127 | const getButtonStyles = ({ isPressed, tokens }) => ({ 128 | background: isPressed ? 'blue' : 'white', 129 | text: !isPressed ? 'blue' : 'white', 130 | }); 131 | 132 | export const Button = ({ children, ...props }) => { 133 | const { isPressed, events } = useButton(props); 134 | const styles = getButtonStyles({ isPressed }); 135 | return ( 136 | 139 | ); 140 | }; 141 | ``` 142 | 143 | For how to allow style overrides, see [Composition](#Composition) 144 | 145 | ### Why? 146 | 147 | Emotion gives us several benefits over other approaches: 148 | 149 | - Styles can be composed directly, without introducing the need for additional components 150 | - Dynamic styles (and the props or state they are based on) can easily be codified in the `getStyles()` function 151 | - Automatic SSR support with no additional server or build configuration required (this is important when publishing packages to npm that should have no understanding of where or how they may be used) 152 | 153 | > Performance notes? 154 | 155 | > Best practice for structuring styles in react. 156 | 157 | ## Accessibility 158 | 159 | > Resources for best practices around accessibility 160 | https://www.wuhcag.com/wcag-checklist/ 161 | https://inclusive-components.design/ 162 | https://www.udacity.com/course/web-accessibility--ud891 163 | https://a11yproject.com 164 | 165 | > Dom to provide (?) 166 | 167 | ## Composition 168 | 169 | ### Props 170 | > reflected attributes as props 171 | > props best practices 172 | 173 | ### Types of Components 174 | 175 | When thinking about composition in a design system, it's helpful to break down the components in your design system into the following types: 176 | _Note that a package in the design system may include one or multiple components, of the following types. Not all components in a package must be exported._ 177 | 178 | - **Elements** 179 | - design system components that do not have internally managed state that reflect styles and attributes onto a dom element. 180 | - **Primitives** 181 | - design system components that do have internally managed state generally only consist of one primary identifiable component. 182 | - **Compound Components** 183 | - design system components that consist of multiple primitives. 184 | - **Composite Components** 185 | - components comprised of multiple components some of which are published elsewhere in the design system. 186 | 187 | The term "stateful", as applied to components, may mean state that is managed internally by the component or accepted as props. 188 | 189 | ### Spreading props and attributes into Views 190 | 191 | Prop spreading is a amenable pattern if there is only one primary dom element. 192 | Prop spreading is not as fine if you have multiple meaningful dom elements in your component. In these situations it is best to have a more targeted strategy for passing attributes and props down to key elements ([see overrides](#Overrides)). 193 | 194 | ### Wrapper Components 195 | 196 | Wrap components to add features, rather than blowing out the complexity of your low-level components, and their increasing API/prop surface area. 197 | 198 | For example, if your basic button takes an `isPressed` prop, and you want to add a toggle button to your design system, you can achieve the effect by creating a wrapping component that manages the toggle state: 199 | 200 | ```js 201 | const ToggleButton = props => { 202 | const [toggled, setToggled] = useState(false); 203 | const handleClick = e => { 204 | props.onToggle && props.onToggle(e, !toggled); 205 | setToggled(!toggled); 206 | }; 207 | return