CMS Component Library
Simpleview CMS Component Library
Table of Contents
Quickstart - A guide to setting up the repo
NPM Scripts - A list of scripts available in the package.json
Repo Structure - An guided explanation of the repo stucture
Unit Testing Overview - Overview and example of unit testing with Jest
Storybook Stories Overview - Overview and example of stories in Storybook
NPM Package - Deploying the npm package
References - A list of useful links and resources, including snippet information
Quick Start
-
Install NodeJS
- For Powershell: Download the Windows installer (LTS version)
- For WSL/Ubuntu: Run the commands below in the terminal:
curl -fsSL https://deb.nodesource.com/setup_lts.x | sudo -E bash -
sudo apt-get install -y nodejs
-
Clone this repository to your local machine
- Example using TortoiseGit:
- Navigate (or created as needed) to D:\cms30\ via File Explorer (this is the recommend folder location, but not required).
- Right click inside the folder and select "Git Clone..."
- Use
git@github.com:simpleviewinc/cms-component-library.git
for the URL. This will use your global GitHub user keys setup during the sv-kubernetes setup. - Click the button labeled "OK" and wait for the repo to checkout. This will create a folder called cms-component-library at D:\cms30\cms-component-library.
- Example using terminal or Windows CMD:
- In your terminal, navigate (or created as needed) to D:\cms30\ or ~/cms30 (this is the recommend folder location, but not required).
- Execute
git clone git@github.com:simpleviewinc/cms-component-library.git
cd D:/cms-30 # or whichever folder you are saving this in
git clone git@github.com:simpleviewinc/cms-component-library.git
-
Install Dependencies
- Open CMD Prompt (or your terminal of choice) and cd to D:\cms30\cms-component-library:
cd cms-component-library
- Execute
npm install
cd cms-component-library
npm install
-
Configure VS Code
-
Download the ESLint extension for VS Code.
-
Open your command palette (Ctrl+Shift+P
on Windows and Cmd+Shift+P
on Mac) and search for settings. Select the "Preferences: Open Settings (JSON)" option.
-
Add the following JSON block to your settings.json file:
"eslint.validate": [
"javascript",
"javascriptreact",
"typescript",
"typescriptreact",
],
"editor.codeActionsOnSave": {
"source.fixAll.eslint": true,
},
-
Start Storybook
Storybook is the main method of local testing.
- Open CMD Prompt (or your terminal of choice) and cd to D:\cms30\cms-component-library:
cd cms-component-library
- Execute
npm run storybook
- Visit
http://localhost:6006
on your local machine
cd cms-component-library
npm run storybook
Back to top
NPM Scripts
A list of the scripts available via package.json
and their functions. Scripts are run via the command npm run [script]
storybook
: Starts up Storybookbuild-storybook
: Builds storybook for production (GitHub Pages)code-quality
: Run type-check, lint, and prettiertype-check
: Run TypeScript against all code to check for type errorslint
: Lint all code, fix anything that can be fixed by eslint
in the processprettier
: Format all code, overwrite filestest
: Run all testsbuild
: Build NPM Package to dist
folderpublish
: Publish NPM release
Back to top
Repo Structure
.storybook
: Configuration for Storybook.vscode
: Global snippets__MOCKS__
: Jest mocks, used to stub out API or filesystem calls - Learn Moresrc
: Main source code path
index.tsx
: Main export for NPM package, if a component is not exported here, it won't be in the NPM package (More on NPM below)components
: React components and their corresponding CSS files
ComponentName/ComponentName.tsx
: The component itselfComponentName/ComponetName.spec.tsx
: Tests for ComponentName
component (More on tests below)ComponentName/ComponentName.stories.tsx
: Stories for ComponentName
componet. (More on stories below)ComponentName.module.css
: CSS styles for ComponentName
stories
: Storybook Introduction and stories not tied to a component
Introduction.stories.mdx
: The intro page of storybook that outlines the storybook structureassets
: Assets for the introduction story and others not tied to specific componentsdocumentation
: Stories not tied to specific components, typically to display foundation styling
styles
: Global CSS files
global.css
: Globally scoped CSSnormalize.css
: Cross-browser default styles rebootfoundations.css
: Global CSS variables (will be replacing swatches.css
in the future)swatches.css
: Global CSS variables (formerly variables.css
)
hooks
: Path for all custom hookstypes
: Path for all shared typeslib
: Old SV libraries converted to TypeScriptutils
: Generic re-usable utilities
.eslintrc.yml
: ESLint configuration.prettierrc
: Prettier configurationjest.config.ts
: Jest configurationjest.setup.ts
: Jest setup (runs before all tests)
Back to top
Unit Testing
We use Jest and React Testing Library to unit test every component. We also include jest-axe unit tests in every component test suite for basic accessibility coverage.
Unit tests are saved as ComponentName.spec.tsx
As an example of a basic test, here we are testing the Link component using the getByText query:
import React from 'react';
import { render } from '@testing-library/react';
import Link from '../Link';
import { axe, toHaveNoViolations } from 'jest-axe';
expect.extend(toHaveNoViolations);
describe('Link Component', () => {
it('Renders Correctly', () => {
const to = {
url: 'https://simplevieweinc.com/',
target: '_blank',
};
const childText = 'test text';
const rel = 'noopener noreferrer';
const { getByText } = render(
<Link
to={to}
rel={rel}
>
{childText}
</Link>,
);
const linkElement = getByText(childText);
expect(linkElement).toBeDefined();
expect(linkElement).toHaveProperty('target', to.target);
expect(linkElement).toHaveProperty('href', to.url);
expect(linkElement).toHaveProperty('rel', rel);
});
it('should not have any testable a11y violations', async () => {
const { container } = render(
<WrapLink
link={{
url: '/',
}}
data-testid='wrap-link-test'
>
Test Text
</WrapLink>,
);
const results = await axe(container);
expect(results).toHaveNoViolations();
});
});
Back to top
Stories
Storybook is an open source tool for building UI components and pages in isolation. It streamlines UI development, testing, and documentation.
Storybook Documentation
We use Storybook to document our components. Storybook auto-generates documentation from comments in the component code, so it's crucial to add clear and contextual comments directly in the component files, not in the story files.
An example of the Docs page for the Link component
Here is an example showing the comments for the Link component's props that are automatically converted to Storybook Docs:
export type LinkProps = {
to: LinkAsset;
target?: '_self' | '_blank' | '_parent' | '_top';
}
In the above code example, the LinkProps
will automatically render like this:
NOTE: In the above code example the comment /** **/
that is directly above the prop is used in Storybook as documentation for that prop. Storybook will be able to auto-detect the type and default (most of the time).
After the props are declared, the component description should be added that explains the general purpose or function of the component as well as any helpful clarifications. This will also display at the top of the Storybook Doc.
Here's an example below of the comments for the Link component. If you visit the Link component in Storybook you can see these comments translated into the Link description at the top of the page.
Storybook Story Example
Stories are saved as ComponentName.stories.tsx
Here is an example of a story for our Link component:
import React from 'react';
import { Link } from '../components';
export default {
title: 'UI Controls/Link',
component: Link,
};
const Template: StoryFn<typeof Link> = (args) => {
const { children } = args;
return <Link {...args}>{children}</Link>;
};
export const Standard = Template.bind({});
Standard.args = {
to: {
url: '/',
target: '_self',
},
target: '_self',
variant: 'link',
children: 'I am a link',
};
export const SecondStandard= Template.bind({});
Standard.args = {
to: {
url: '/',
target: '_blank',
},
target: '_blank',
variant: 'link',
children: 'I am a second link',
};
Back to top
NPM Package
See the NPM Release Documentation for instructions on deploying new versions to NPM.
Back to top
References and Resources
Snippets
We have included some helpful boilerplate snippets for VSCode users.
There are currently the following named snippets:
svcomponent
- the boilerplate for a new componentsvtest
- the boilerplate for a new Jest test suitesvstory
- the boilerplate for a new Storybook story
To use these snippets:
- Create the folder for the new component and the relating file (
NewComponent.tsx
, NewComponent.spec.tsx
, NewComponent.stories.tsx
respectively) - Type the snippet name in the body of the file and press
Tab
- The boilerplate should render and allow you to change the
ComponentName
, if needed - Tab through to update the name of secondary parameters, if any.
Helpful Links and Documentation
Back to top