- When does a component go in the design system?
- Maintaining Assets
- Git Strategy
- Code Standards
- Code Style
- Release Process
- Rules
- Build process
- ES Modules
Icons are exported from Figma and stored in the adjacent svg
directory.
Each icon must:
- have it's own
20×20
artboard.- in other words, a
viewBox
that is at least20
on one axis:- good:
viewBox="0 0 20 18"
,viewBox="0 0 20 20"
. - bad:
viewbox="0 0 20 34"
.
- good:
- in other words, a
- contain only one exportable layer, which has:
- a single path or group.
- a kebab-case layer name prefixed with
icon-
- this is essential for the build step.
- the export format defined as "SVG".
- have its color fill set to
#DE1E7E
(remember "DELETE") if you want the color to be modified.
Any changes to this Sketch file should be committed as well as the Sketch-generated SVGs. To export all SVGs in Sketch, select File > Export
and in the next step choose the svg
directory as the output location.
For performance benefits (such as code-splitting) we opted for creating individual React components for each icon, rather than one single component.
We make use of SVGR, to transform the above SVG icons in assets
to React components in sportsbet-icons
.
To update/add icons run: yarn assets build
- Runs SVGR based on the config options.
- Builds React
.tsx
files for each component with the template.
Commits follow the Angular Commit Message Format. When committing changes, make use of the Commitizen CLI to generate consistent commit messages:
yarn commit
As a developer, you will you be branching and merging from develop
, our base branch.
Consider origin/master
to always represent the latest code deployed to production.
Use supporting branches for all new features and bug fixes. Unlike the base branch, these branches have a limited life-time and should be removed after merging.
The different types of branches should be named as follows:
- Feature:
feature/feature-name
- Bug fix:
fix/fix-name
-
Create the branch locally and then push to GitHub if it does not exist yet.
A branch should always be 'publicly' available, and should never exist in just one developer's local repo.
-
Make a pull request.
-
Add the
in progress
tag until ready for review. -
Periodically, keep changes up to date with develop via
git rebase develop
. -
Grab a review and remove the
in progress
tag. -
One approved, it's down to you to merge the branch into
develop
. Code can only be contributed todevelop
via using pull requests. -
Delete your branch.
git checkout develop
git pull
git checkout your-branch
git rebase develop
-
Pick your base commit, where you want add all other commits on top of.
git log
or the more visually friendly
git log --oneline --graph --all --decorate -n 30
-
git rebase -i hash
- launches interactive shell where you choose your commits to squash -
git push -f
- force push your git changes
Use merge - not rebase whenever you've already pushed.
Never use git rebase
on public branches.
Consider using git rebase
only if you want to avoid spaghetti-history in your local branch.
Long-lived feature branches present problems when you need to build code on top of unfinished work. Merge unfinished features into the develop
branch (following the steps outline above) so others can build off their work, but keep them hidden from your users and testers behind feature flags. Enable the flag in development to use the feature without the changes affecting anyone else. Once the feature is finished, you can remove the flags or use them to roll out to selected users and testers.
All features should attempt to conform to as many items on The A11Y Project's Web Accessibility Checklist as possible. If a checkbox can't be completed, the justification should be documented for future reference.
As part of our TypeScript linting process, we make use of react-a11y
rules (surfaced via tslint-microsoft-contrib
) to catch any common issues. react-a11y-role-has-required-aria-props
is currently disabled for incorrect results.
Mobile devices are the most commonly used methods of browsing the web. When it comes to designing and developing your component, always build with mobile in mind first.
Need to modify the style at specific breakpoints? Scale your changes upwards; build for mobile by default and then add media queries for changes on larger sizes.
Want to use CSS Grid? Set your component to display: block;
by default to stack items on mobile and other unsupported devices, then implement your grid at larger breakpoints.
Code formatting is handled automatically via Prettier on pre-commit. However, you could install an IDE extension or run manually via yarn format <prettier-args>
.
Linting will catch any further non-formatting issues:
- TSLint
- Config: tslint.json
- Note: As TSLint does not yet support TypeScript project
references
(palantir/tslint#4137), TSLint must be executed vialerna run
to treat each package correctly.
Separate concerns on a component basis, rather than the more traditional "style vs. function".
With Styled Components we can take advantage of keeping style, markup and logic tightly bound together as a single .tsx
file. A component file should be defined in the following order:
- Imports
- External (e.g.
node_modules
) - Internal (i.e. a different package from the design system)
- Component partials
- Styles
- Settings (e.g.
const
) - Helper functions
- Markup / logic
- Exports
Each component/consumable feature must have a README that follows the appropriate package's pre-defined .templates/
:
This should be written in .mdx
syntax, which will be included automatically in the Style Guide.
For a basic component, the directory structure would look something like this:
+————————————+
│ Button │
+————————————+
components
├── button
│ ├── README.mdx
│ └── index.js
└── …
For larger components, consider breaking down into smaller partials:
+——ComponentName——+
│ │
│ Title │
│ │
+—————————————————+
│ │
│ Caption │
│ │
+—————————————————+
components
├── button
├── component-name
│ ├── caption.tsx
│ ├── index.ts
│ ├── README.mdx
│ ├── settings.ts
│ ├── title.tsx
│ └── utils.ts
└── …
settings
Common constants/raw values that can be re-used across the different component partials.
utils
Styles that are unique to the component
but need to be shared across the partials.
These styles should be flat/stateless and not bound by any form of functionality, making use of the CSSObject
type from Styled Components for compatibility.
-
Components should be defined in PascalCase.
For example:
<ComponentName/>
-
Component partials should be prefixed by the component name:
For example:
<ComponentNameTitle/>
-
-
Flat re-usable styles should be defined in camelCase to differentiate.
- For example:
<div css={componentNameSizing}/>
- For example:
Thanks to Lerna and Commitizen, we can generate version bumps and CHANGELOGs for each package and release automatically.
-
Assuming that all changes to be released have followed the Git Workflow outlined above, raise a pull request from
develop
intomaster
. -
Ensure the pull request is up to date with
master
. -
Obtain at least 1 approval.
-
Click the "Merge Pull Request" button to trigger an automatic release, monitoring progress in CircleCI.
- If successful, a new tag will be visible, along with new package versions on NPM.
-
Communicate the release to the team!
- All your files should be named after the actual component. So the component
GroupIconCurrency
is inside the fileGroupIconCurrency.tsx
. - All your components should export a single default React component. This is only so we can enable tree shaking.
- All first level subfolders inside
/src/
are considered public. People will useimport { } from @heathmont/sportsbet-package-name/folder
to import files from those folders directly. - You are required to auto-generate an index file to for each subfolder which uses named exports to re-export all exports inside the folder + sub folders. This is required for tree shaking.
- You are required to auto-generate an index file to for your package which uses named exports to re-export all exports. This is required to allow lerna to import the project proeprly.
All packages are built in 2 separate formats, commonjs
and es
.
All code belongs in /src
folder. When running yarn build, it will automatically generat a lib
folder based on the code
inside src
.
First we transpile commonjs
format modules into the lib
folder directly.
Second we transpile es
format modules into the lib/es
folder.
Third we generated typescript definitions into the lib
folder directly.
Before we release, we will:
- Copy all files from
lib
folder into the root folder. - Update the
files
,main
,module
andtypings
fields in package.json
After we release, we will:
- Remove all the files we copied over from
lib
. - Undo the changes to
files
,main
,module
andtypings
fields in package.json