Currently, this project is closed to any external contributions. Any pull request made against this project from external sources will likely be closed. If you would like to make changes to this project, please fork this project.
When creating new components in this repository, there are a few common developer flow patterns that can help new contributors get started. This section maps out the process for creating a new component from start to finish.
Be sure to validate the requirements are met before implementation begins. After
requirements have been met, proceed with installing dependencies using the yarn
or yarn install
command from the root folder.
At this point, familiarize yourself with the new components folder located in ./src/components/
.
This is where your new component implementation will exist.
To create a new component using a our component template, run the yarn generate:component
script
from the root of this project. This will ask you a collection of questions to create the component.
Answer these questions to the best of your ability. Once the script fully executes, a new folder
containing your component should propagate in ./src/components/
. This will be where your
implementation begins.
Once the new component has been created using the template script, you can simply run yarn start
to launch a live example of all of the components, including your new one! Once Storybook finishes
compiling during the yarn start
script's execution, it will hot-launch a browser window. Browse to
your component using the menu on the left to view the current state of your component. Note: This
will update when ./src
files change.
Now you are ready to start making changes to source files! Be sure to review New Component File Details to have a better understanding of what each file's purpose is.
Below is an example of the flow needed to add a prop and consume it in the examples:
{component}.types.ts
- Add the new prop-type to the component'sProps
interface.{component}.constants.ts
- Add the default and options for the prop if needed.{component}.tsx
- Update the react component to handle a new prop and render it.{component}.style.scss
- Add some styles to the component. If a token update is needed, see this contribution guide.{component}.stories.args.ts
- Add a new key:value so that the prop is controllable in storybook.{component}.stories.tsx
- Create a new sub-story using a template that shows the new prop states.{component}.unit.test.tsx
- Add the prop as a snapshot and attribute test.{component}.stories.docs.mdx
- You may want to update the general docs if the prop added is very explicit in how its handled. Follows Git markdown syntax.
After the component has been validated visually via yarn start
in a storybook, we can run the
tests to generate the snapshots as well as confirm the component passes its tests. Use yarn test
to do this, and yarn test -u
to update snapshots if needed.
Before submitting changes, it is recommended to run yarn ci:build
to validate that the application
builds as expected before allowing our continuous integration platform to run this step. After this
runs, you can run yarn storybook:start:docs
to serve the built files for viewing. If everything
looks good, create a new branch with your changes and push the changes in your branch
[email protected]:momentum-design/momentum-react-v2.git and create a PR to begin the review process.
Once your Pull Request has been submitted, our automation platform will begin testing and analysis of your changes. An approval is required before your changes can be merged.
In order to begin making contributions to this project, NodeJS must be installed. The currently used NodeJS version is defined in the .nvmrc.
While NodeJS can be installed manually, we recommend to use
NVM - Node Version Manager instead. It can automatically switch to
the correct version of NodeJS based on the .nvmrc
or download it if necessary.
This project use Yarn Package Manager via
NodeJS corepack. To activate it, just run corepack enable
in the root of the project after NodeJS installed.
The following definition provides an overview of commonly used files, when contributing, within the file structure of this project:
./ # project root
+-+ config/ # configuration files for this project
+-+ dist/ # built distributables
+-+ docs/ # build documentation
+-+ scss/ # legacy component styles ported from @momentum-ui/core
+-+ src/ # source code for this project
+-- components/ # typescript react components
+-- examples/ # legacy examples
+-- helpers/ # enzyme test helpers
+-- legacy/ # legacy react components cloned from the original @momentum-ui/react project
+-- storybook/ # storybook utilities
+-- index.js # entry file for all module exports
While there are other files and directories within the project that contain other project resources, most contributors will only interface with the above-listed items.
Most feature contributions to this project will be implementing new React components within the
./src/components/
directory. We ask that all contributions that include new React components
follow the following directory model:
./src/ # source code directory
+-- index.js # global react component module entry point
+-+ components/ # typescript react components directory
+-- index.ts # typescript react component module entry point
+-+ {component}/ # typescript react component directory
+-- index.ts # entry point for component, should contain all exports [component, constants, types, etc]
+-- {Component}.constants.ts # constants scoped to this component [styles, text, etc]
+-- {Component}.stories.args.ts # global story argTypes.
+-- {Component}.stories.docs.mdx # storybook stories description this component.
+-- {Component}.stories.tsx # storybook stories for this component [be robust, as these are tested visually]
+-- {Component}.style.scss # scoped styles, class selectors should follow 'md-{component}' for the root selector
+-- {Component}.tsx # react component file
+-- {Component}.types.ts # scoped types for this component [props, state, etc]
+-- {Component}.unit.test.tsx # scoped unit tests [snapshot, attribute, and action tests] for this component
+-- {Component}.unit.test.tsx.snap # scoped unit test snapshot for this component. Autogenerated on test run.
After a component has been implemented, it will need to be added to the ./src/index.js
and
./src/components/index.ts
files for exporting. Be sure to add the new component in the
appropriately commented section within these files once the component is ready.
When generating a new component, the generate:component
script can be used to automatically
generate a majority of the boiler-plate for the new component. Be sure to validate that the folder's
name is properly capitalized and that your component is exported via the various index
files
appropriately after generation is complete.
When a changes occur against the new React components in this project, a few standards must be met:
- All logical code must be written in TypeScript.
- Style definitions must be written without the help of functional style generations, such as mixins.
- Component entry points must export constants and types for easy downstream consumption.
- Component style assignment should be via attribute selectors prefixed with
data-
and classes prefixed withmd-{component}
. - Component styles should be referenced in the renderer as constants in
{component}.constants.ts
. - Component constants should be used for all limited prop variations and defined in a
{component}.constants.ts
file. - Components should be functional whenever possible.
- Components must include unit and integration testing with jest.
- Component unit tests should separate snapshots, attributes, and actions respectfully.
- Components must include visual testing with storybook.
- Component stories should be written to provide an example for each provided prop.
- Components must include documentation with storybook.
- Component documentation must be fully specified, see other component stories in this project for examples.
- Components should have a default story:
Example
which allows for mutation of all props. - Specific prop stories should remove the associated prop from the arglist.
- For components with large amounts of variations, a
Common
story can be written with common examples. - Most components should have a
{component}.documentation.mdx
file that includes a description of the component.
Legacy components should not contain any larger feature work, and are currently in the maintenance SDLC state. Below is their directory model:
./ # project root directory
+-+ scss/ # styling sub-module
+-+ components/ # scoped styling entry directory
+-+ {component}/ # scoped component styling
+-- {styles}.scss # various scoped styling definitions
+-+ src/ # source code directory
+-- index.js # global react component module entry point
+-+ legacy/ # legacy react components directory
+-- index.js # legacy react component module entry point
+-+ {component}/ # legacy react component directory
+-- index.js # entry point for component, contains the component renderer
+-+ examples/ # examples documentation fo visual testing and docs
+-- index.js # examples module file, imports all files from directory needed
+-- KitchenSink.js # renderer for component states, includes all component states
+-- {state}.js # scoped state for this component
+-+ tests/ # scoped unit test directory
+-- index.spec.js # jest unit test file
+-- index.spec.js.snap # automatically-generated snapshot file
While most changes to these components wont require any changes to the module entry files, be aware that changes in those files may be needed in broad-scoped implementaitons.
The following section includes definitions and details on the scripts available within this package. Each script is broken into its appropriate scope, with the exception of the general scripts immediately below. The general scripts should be used in most cases, while the auxiliary scoped scripts can be used to perform specific actions.
build # Compiles documentation and source for distribution.
lint # Performs static analysis of './src'.
lint:watch # Performs static analysis when a file is changed in './src'.
test # Performs tests against './src' files.
test:watch # Performs tests against './src' when a file is changed.
start # Starts storybook in watch mode for development.
start:components # Starts storybook in watch mode.
start:examples # Starts the examples in watch mode.
start:watch # Starts persistent static analysis, testing, and rendering on file change.
ci
scripts are for strict usage with our continuos integration system.
ci:build # Builds source, docs, and specific tests into the './dist/{cjs|esm}` folder.
ci:test:examples # Launches and tests examples using the built project files.
ci:test:lint # Performs static anaysis [linting] of './src' and './config' folder files.
ci:test:src # Runs unit tests within the './src' folder.
ci:test:storybook # Launches and tests storybook using the built project files.
docs
scripts are used for building servable documentation.
docs:clean # Removes the './docs' directory and contents.
docs:build # Cleans built documentation and builds all documentation from './dist'.
examples
scripts are used for operating the examples application [kitchen sink].
examples:build # Cleans built examples and builds from './dist'.
examples:clean # Removes the './docs/examples' directory and contents.
examples:start # Starts source examples from './src'.
examples:start:docs # Starts built examples from './docs/examples'.
examples:start:esm # Starts built examples from './dist/esm'.
examples:start:src # Starts source examples from './src'.
examples:test # Performs visual tests of the built examples.
generate
scripts are used to automatically create files within the ./src directory to promote
consistent code styling.
generate:component # generates folder structure, files and manages imports of a new component via prompts
lint
scripts perform actions related to static analysis.
lint:config # Performs static analysis of the './config' directory.
lint:src # Performs static analysis of the './src' directory.
source
scripts perform actions against source files in this project.
source:build # Cleans built files from './dist' and builds types, esm, and cjs bundles.
source:build:styles # Builds style files from './src' into their paired './dist' folders.
source:build:clean # Removes the './dist' folder and its contents.
source:build:cjs # Builds the './src' files into './dist/cjs' as CommonJS.
source:build:compile # Builds CommonJS and ESModule from './src' to './dist'.
source:build:esm # Builds the './src' files into './dist/esm' as ESModule.
source:build:stories # Builds the storybook files into './dist' for production testing.
source:build:documentation # Builds the storybook mdx files into './dist' for production testing.
source:build:fonts # Builds font files from './src' into their paired './dist' folders.
source:build:watch # Watches all ts,tsx,js and scss files and builds via source:build
source:test # Runs unit and integration tests within './src'.
storybook
scripts are used for operating Storybook actions.
storybook:build # Cleans the built storybook and builds a storybook from './dist/esm'.
storybook:build:cjs # Builds a storybook to './docs' from './dist/cjs'.
storybook:build:esm # Builds a storybook to './docs' from './dist/esm'.
storybook:build:src # Builds a storybook to './docs' from './src'.
storybook:clean # Removes the './docs' folder and its contents.
storybook:start # Starts the storybook examples from './src'.
storybook:start:docs # Starts the storybook examples from './docs'.
storybook:start:src # Starts the storybook examples from './src'.
storybook:test # Performs visual tests of the built storybook.
styles
scripts perform actions against style files within the ./scss
folder.
styles:build:css # Builds './scss' files into a bundled css file.
styles:build:settings # Generates scss files from settings within the './scss' directory.
styles:build:tokens: # Generates scss files from tokens within the './scss' directory.
styles:makeIECompatible: # Makes a single scss file IE compatibile w.r.t. css vars
styles:makeIEIncompatible: # Removes css compatibility lines generated by styles:makeIECompatible
styles:tokenCheck: # Checks that css vars used in the scss files reference existing tokens
With the current state of this project, all changes must be submitted as pull requests from branches that exist on this repository. This gives our automation platforms access to the code during their cycles. If a pull request is generated from a fork of this repository, and not a branch on this repository, our CI platform will not run any tests due to the privacy settings of this project.
Since upcoming changes to this project will include the usage of an active CD changelog, we recommend validating that every commit meets conventional commit standards, specifically those set by @commitlint/config-conventional. This will allow our changelog to build appropriately once a change is merged into the default branch of this project.
By contributing your code to the momentum-react-v2
GitHub repository, you agree to license your
contribution under the MIT license.