apple_xyz v1.0.0-beta.24
The Spruce Design System (SDS) - LIVE Storybook
Installation
SDS is published as an NPM package here.
yarn add @hellospruce/spruce-design-system
Setup the SDS global theme
// yourapp/index.tsx
import { GlobalThemeProvider } from '@hellospruce/spruce-design-system'
ReactDOM.render(
<GlobalThemeProvider>
<App />
</GlobalThemeProvider>,
document.getElementById('root')
)
Customise the Theming
The GlobalThemeProvider
is a wrapper for the styled-components ThemeProvider
that provides a Spruce default theme.
The defines global styles for typography, buttons, fonts, and an optimized CSS reset. This can be viewed in the GlobalThemeProvider.tsx.
It can be configured with a custom theme object that is merged with the SDS defaults, and global styles with (styled-components createGlobalStyle
).
Create a custom Theme configuration file
You'll want to extend the styled-components DefaultTheme
type as mentioned here.
// theme.ts
import { GlobalTheme } from '@hellospruce/spruce-design-system'
// Override SDS default theme
export const theme = { colors: { special: 'purple' }, myNewThemeProp: 'whatever' }
// Extend the styled-component DefaultTheme with our extended SDS theme
declare module 'styled-components' {
export interface DefaultTheme extends GlobalTheme<typeof theme> {}
}
Configure the provider
// yourapp/index.tsx
import { createGlobalStyle } from 'styled-components'
import { GlobalThemeProvider, GlobalTheme } from '@hellospruce/spruce-design-system'
import { theme } from 'myapp/src/theme.ts'
const CoolGlobals = createGlobalStyle`
p { color: pink; }
`
ReactDOM.render(
<GlobalThemeProvider theme={theme}>
<CoolGlobals />
<App />
</GlobalThemeProvider>,
document.getElementById('root')
)
Use a Component & apply your custom Theming
// yourapp/app.tsx
import { useTheme } from 'styled-components'
import { Container, Panel } from '@hellospruce/spruce-design-system'
const App = () => {
const theme = useTheme()
return (
<div className='App'>
<Container bg={theme.colors.special}>
<Panel width='100%' p={4} color='primary.0'>
Your apps awesome content inside an SDS Container & Panel. This text would be the first
colour in the theme colors.primary Array.
</Panel>
</Container>
</div>
)
}
export default App
Component demos and docs
Component docs are kept within the folders of the component. The Components & their docs can be view on Storybook.
Contributing
Development
SDS is a React components library using Styled Components and Styled System for theming & styling.
SDS uses Storybook as a UI development environment, which documents self-contained presentational components, and allows for controlled testing. Storybook itself is an open-source tool and platform that can be deployed to something like Zeit Now or run locally. We are using it to document the Spruce Design System. Both the Spruce Storybook and the Spruce Design System exist in the same repo for easier deployment.
Running Storybook locally
git clone
the latest spruce-design-system- Run
yarn
to install dependencies. - Run
yarn storybook
to start Storybook locally.
Linking the SDS locally to a local React App
You can use yarn link, but I recommend checking out Yalc. This article helped me understand using Yalc.
Linting & Formatting
This project is configured with ESLint and Prettier for code quality.
If you use VSCode, install packages ESlint and Prettier. This project has Git versioned .vscode/settings.json
so after restarting VSCode you should be all setup.
If not, it's recommended to setup "format on save" settings with your IDE/Editor of choice that uses Prettier that respects ESLint settings... Otherwise, just run the below before opening a PR.
yarn format # Runs Prettier (write files)
yarn checkcode
Adding components
Generally speaking, a component should be a candidate for inclusion in the Design System if it will be implemented across multiple platforms or properties. This is because a key benefit of the design system is that it is a single source of truth, and any updates made will be reflected across all platforms.
There are 4 main files to add to a component directory.
*.tsx
contains the TS React component. Ensure it is properly typed otherwise it will throw errors during build.*.docs.md
is a markdown file for documenting props and examples of implementation. It will display alongside the component in Storybook.*.stories.tsx
is a Storybook file - it should import the component and display examples of usage. More information on Storybook files here.index.ts
expose public exports (think what should other components be able to access from this module?)
Because of the index.ts
export file, it's encouraged to break your component up into as many logical files as needed. No need to have 1 big component file with 10 exported functional components, etc.
Note, the components folder does not barrel export in a components/index.ts
to prevent circular dependencies, and bad import/export patterns that lead to hard to debug issues.
Example:
cd src/components
mkdir MyComponent
touch MyComponent.docs.md MyComponent.stories.tsx MyComponent.tsx index.ts
- Don't forget to export your component in the src/index.ts file so it's accessible by consuming apps (i.e what ever values are exported there are importable by apps that use this library).
- Run storybook locally to run your component (must have a working
*.stories.tsx
file).
Testing
SDS is setup with Jest with additional utilities provided by testing-library. Specifically testing-library/react and testing-library/jest-dom.
A good tutorial on getting started with the utilities testing-library provides here.
The Jest environment is also configured with a jest-styled-components package. This adds a utility method .toHaveStyledRule
to expect matchers - docs here.
Though, Jest Snapshots seem to be a better way to capture styled-component styles, as it also incorperates styled-system attributes. It is recommended that snapshots are used to test your components UI, there are examples of this in the project.
First to get started, let's create our testing directory (with your component directory).
mkdir __tests__
touch __tests__/MyComponent.test.tsx
Most simple "hello world" test is to check that it even renders.
// MyComponent/__tests__/MyComponent.test.tsx
import React from 'react'
import { render } from '@testing-library/react'
import { MyComponent } from '../MyComponent'
describe('<MyComponent />', () => {
test('renders', async () => {
render(<MyComponent />)
})
})
As per documentation for styled-components Jest Snapshot adapter. Creating a snapshot for a styled component can be done like below.
test('UI snapshot', () => {
const { container } = render(<MyComponent />)
expect(container).toMatchSnapshot()
})
This will create a __snapshots__/
with a snap file when you run your first test. You can view this to see the magic.
yarn test
When changes are made to the UI (html/css) of your component that are intended, you can update the snapshot with the below command.
yarn test -u --testNamePattern **/MyComponent.test.tsx
Pull requests
Checklist
- your branch is on a FORK of the spruce repository
- your component is working and documented (
*.docs.md
) with storybook locally yarn validate
to validate ts compilation.yarn lint
is without warningsyarn test
Jest unit test are passingyarn build
successfully compiles your changes to a production build with Rollup.js (just to be sure!)
Deployment & Versioning
Storybook
- Run
yarn build:storybook
to bundle the Storybook platform for deployment. cd .storybook/spruce-design-system
to navigate to the bundle.npx vercel login
npx vercel
and follow deploy prompts
NPM
A version should be created from master branch using the NPM version API.
IMPORTANT: There are NPM scripts (preversion, version, postversion & postpublish) that will first check your code, publish an NPM version, create a git tag, and finally push the version & tags to github. These scripts can be viewed in the package.json.
Checklist BEFORE running the npm version
command:
- Your CLI is logged in with NPM (
npm login
) and you're apart of the Spruce NPM Team. - You are a GitHub project administrator (master branch push rights required)
- The CHANGELOG has been updated (this change should be committed to a "release/x.x.x" branch and merged to master)
- You are checked-out onto the master branch which contains the latest changes.
- You're aware that when running
npm version
, if code quality checks are successfull, a version will be published to NPM which cannot be removed easily.
Deploying a new version
# This will increment the beta version (i.e 1.0.0-beta.0 => 1.0.0-beta.1)
npm version prerelease --preid=beta
# This will increment the patch version (i.e 1.0.0 => 1.0.1)
npm version patch
If successful, the last step will be to go to the Github and create a Github release from the newly pushed Git Tag.
Create a version without pushing to remotes
If you want create a "dry run" version, or do it in stages, use the --ignore-scripts
flag.
This will just version the package.json, create a commit, and create a local git tag.
# Still check your code quality
yarn checkcode
# Create a version ignore npm scripts (hooks).
npm version patch --ignore-scripts
3 years ago