npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2024 – Pkg Stats / Ryan Hefner

@simpleview/cms-component-library

v0.1.24

Published

Simpleview CMS Component Library

Downloads

72

Readme

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

  1. 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
  2. Clone this repository to your local machine

    • Example using TortoiseGit:
      1. Navigate (or created as needed) to D:\cms30\ via File Explorer (this is the recommend folder location, but not required).
      2. Right click inside the folder and select "Git Clone..."
      3. Use [email protected]:simpleviewinc/cms-component-library.git for the URL. This will use your global GitHub user keys setup during the sv-kubernetes setup.
      4. 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:
      1. In your terminal, navigate (or created as needed) to D:\cms30\ or ~/cms30 (this is the recommend folder location, but not required).
      2. Execute git clone [email protected]:simpleviewinc/cms-component-library.git
    cd D:/cms-30 # or whichever folder you are saving this in
    git clone [email protected]:simpleviewinc/cms-component-library.git
  3. Install Dependencies

    1. Open CMD Prompt (or your terminal of choice) and cd to D:\cms30\cms-component-library: cd cms-component-library
    2. Execute npm install
    cd cms-component-library
    npm install
  4. Configure VS Code

    1. Download the ESLint extension for VS Code.

    2. 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.

    3. Add the following JSON block to your settings.json file:

    "eslint.validate": [
        "javascript",
        "javascriptreact",
        "typescript",
        "typescriptreact",
     ],
     "editor.codeActionsOnSave": {
       "source.fixAll.eslint": true,
     },
  5. Start Storybook
    Storybook is the main method of local testing.

    1. Open CMD Prompt (or your terminal of choice) and cd to D:\cms30\cms-component-library: cd cms-component-library
    2. Execute npm run storybook
    3. 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 Storybook
  • build-storybook: Builds storybook for production (GitHub Pages)
  • code-quality: Run type-check, lint, and prettier
  • type-check: Run TypeScript against all code to check for type errors
  • lint: Lint all code, fix anything that can be fixed by eslint in the process
  • prettier: Format all code, overwrite files
  • test: Run all tests
  • build: Build NPM Package to dist folder
  • publish: 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 More
  • src: 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 itself
      • ComponentName/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 structure
      • assets: Assets for the introduction story and others not tied to specific components
      • documentation: Stories not tied to specific components, typically to display foundation styling
    • styles: Global CSS files
      • global.css: Globally scoped CSS
      • normalize.css: Cross-browser default styles reboot
      • foundations.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 hooks
    • types: Path for all shared types
    • lib: Old SV libraries converted to TypeScript
    • utils: Generic re-usable utilities
  • .eslintrc.yml: ESLint configuration
  • .prettierrc: Prettier configuration
  • jest.config.ts: Jest configuration
  • jest.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'; // react-testing-library
// We do not need to import Jest, when we run tests
// it is Jest that runs these files, so all Jest
// functions are implicit

import Link from '../Link'; // This is the component we are testing

import { axe, toHaveNoViolations } from 'jest-axe'; // Jest-axe provides basic testing for common accessibility issues

expect.extend(toHaveNoViolations); // This adds the jest-axe custom Jest matcher to check for accessibility issues

// We start with `describe`, we are describing our Link component
describe('Link Component', () => {
	// We expect that `it` `Renders Correctly`, you can have
	// multiple `it` blocks if your component is more complex
	// and requires testing different scenarios
	it('Renders Correctly', () => {
		// Here we are defining some variables to use as props
		// for the component
		const to = {
			url: 'https://simplevieweinc.com/',
			target: '_blank',
		};
		const childText = 'test text';
		// This is an extra prop, we also want to make sure they are tested,
		// check the Link component to see where the extra props are passed
		const rel = 'noopener noreferrer';

		// We get any queries we want to use (`getByText` here) from the 
		// `render` function of react-testing-library, and pass in our
		// component with the mock data above, check the documentation
		// for react-testing-library for more available queries
		const { getByText } = render(
			<Link
				to={to}
				rel={rel}
			>
				{childText}
			</Link>,
		);

		// We should see the test within `childText` in the rendered component
		const linkElement = getByText(childText);

		// We expect to have found the element rendered by our component
		expect(linkElement).toBeDefined();
        
		// We expect the `target`, `href`, and `rel` attributes to be
		// added to the element as defined by the Link component. Check
		// the Jest documentation for more on `expect` Matchers.
		expect(linkElement).toHaveProperty('target', to.target);
		expect(linkElement).toHaveProperty('href', to.url);
		expect(linkElement).toHaveProperty('rel', rel);
	});

  // A version of this test is added to every compoonent's unit tests
  // to ensure that there are no testable accessibility (a11y) violations
  // utilizing jest-axe's `.toHaveNoViolations()`.
  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 = {
	/**
	 * The `to` object specifies the URL to link to, and optionally a target that specifies where to open the linked document.
	 */
	to: LinkAsset;
	/**
	 * The target attribute specifies where to open the linked document, overriding the `target` key in the `to` object.
	 */
	target?: '_self' | '_blank' | '_parent' | '_top';
}

In the above code example, the LinkProps will automatically render like this: Storybook Link Props from 'https://simpleviewinc.github.io/cms-component-library/?path=/docs/ui-controls-link--docs'

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.

/**
 * The Link component is used to trigger an action or event where the primary intention is navigation.
 *
 * The `target` property can be specified in two places, either as a property of the `to` object, or
 * as a prop on the Link component itself. If both are specified, the `to` object is ignored.
 * This way, you can override the target without modifing the `to` object.
 */

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';

// The title here translates to the story `Link` in the `UI Controls` folder
export default {
	title: 'UI Controls/Link',
	component: Link,
};

// Render the Link component
const Template: StoryFn<typeof Link> = (args) => {
	const { children } = args;
	return <Link {...args}>{children}</Link>;
};

// `Standard` is a layout displayed in Storybook,
// we can define multiple layouts if needed (e.g. `SecondStandard`).
// The args passed to primary are the props
// that the rendered component will receive.
export const Standard = Template.bind({});
Standard.args = {
	to: {
		url: '/',
		target: '_self',
	},
	target: '_self',
	variant: 'link',
	children: 'I am a link',
};

// `SecondStandard` is an additional layout displayed
// in Storybook, that uses the same Template as `Standard`,
// but with it's own unique props.
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 component
  • svtest - the boilerplate for a new Jest test suite
  • svstory - the boilerplate for a new Storybook story

To use these snippets:

  1. Create the folder for the new component and the relating file (NewComponent.tsx, NewComponent.spec.tsx, NewComponent.stories.tsx respectively)
  2. Type the snippet name in the body of the file and press Tab
  3. The boilerplate should render and allow you to change the ComponentName, if needed
  4. Tab through to update the name of secondary parameters, if any.

Helpful Links and Documentation

Back to top