From dc85daea071d440e5af32baf70198d586f5c1cac Mon Sep 17 00:00:00 2001 From: Adam Stankiewicz Date: Wed, 1 Feb 2023 08:37:51 -0500 Subject: [PATCH] docs: update README and add CONTRIBUTING (#1979) --- CONTRIBUTING.md | 13 ++ README.md | 311 +++++++++++++++++++++++++----------------------- 2 files changed, 172 insertions(+), 152 deletions(-) create mode 100644 CONTRIBUTING.md diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md new file mode 100644 index 0000000000..49e27eda3f --- /dev/null +++ b/CONTRIBUTING.md @@ -0,0 +1,13 @@ +# Contributing + +## Open edX + +Please refer to the ["How to Contribute"](https://openedx.org/r/how-to-contribute) documentation and [Code of Conduct](https://openedx.org/code-of-conduct/) from Open edX for general information on contributing to the Open edX project. + +## Paragon + +The Paragon Working Group accepts bug fixes, new features, documentation, and security patches. You may find open issues [here](https://github.com/openedx/paragon/issues) or by visiting the Paragon Working Group [project board](https://github.com/orgs/openedx/projects/43/views/15). Issues with the "help wanted" or "byte-size" labels may be good candidates to pick up. + +If you'd like to contribute a new component or update an existing component, please consider reaching out to the Paragon Working Group via the channels [described in the README](./README.md#getting-help) to propose your changes. + +The Paragon Working Group looks forward to your contributions! 💎 diff --git a/README.md b/README.md index cf9bcfe8bd..9babdf325a 100644 --- a/README.md +++ b/README.md @@ -1,10 +1,10 @@ # Paragon -![status](https://img.shields.io/badge/status-Maintained-brightgreen) +[![Build Status](https://github.com/openedx/paragon/actions/workflows/release.yml/badge.svg)](https://github.com/openedx/paragon/actions/workflows/release.yml) [![npm_version](https://img.shields.io/npm/v/@edx/paragon.svg)](@edx/paragon) -[![codecov](https://codecov.io/gh/edx/paragon/branch/master/graph/badge.svg?token=x1tZmNduy9)](https://codecov.io/gh/edx/paragon) +![status](https://img.shields.io/badge/status-Maintained-brightgreen) ![license](https://img.shields.io/github/license/openedx/paragon.svg) -[![Build Status](https://github.com/openedx/paragon/actions/workflows/release.yml/badge.svg)](https://github.com/openedx/paragon/actions/workflows/release.yml) +[![codecov](https://codecov.io/gh/edx/paragon/branch/master/graph/badge.svg?token=x1tZmNduy9)](https://codecov.io/gh/edx/paragon) [![NPM downloads](https://img.shields.io/npm/dw/@edx/paragon)](https://www.npmjs.com/package/@edx/paragon) ## Purpose @@ -63,135 +63,12 @@ Please reach out to the Paragon Working Group (PWG): * [Github Issues](https://github.com/openedx/paragon/issues/new?template=blank-issue.md) * [Weekly PWG Meeting](https://calendar.google.com/calendar/embed?src=c_v86shrnegshsqgp4fj2k94u7bc%40group.calendar.google.com&ctz=America%2FNew_York) -## Contributing & Development - -Please refer to the ["How to Contribute"](https://openedx.org/r/how-to-contribute) documentation and [Code of Conduct](https://openedx.org/code-of-conduct/) from Open edX. - -The Paragon Working Group accepts fixes, new features, and security patches. If you'd like to contribute a new component or update an existing component, please consider reaching out to the Paragon Working Group via the channels [described above](#getting-help). - -#### 1. Start the documentation site development server - -The Paragon documentation site serves both as documentation and as a workbench to create your component within. To see your component in action, you need to run the documentation site locally. (Note you need to install dependencies both in the project root and the `www` directory) - -``` -npm run install-all -cd www -npm start -``` - -#### 2. Create new component - -To create new component run - -``` -npm run generate-component MyComponent -``` - -where `MyComponent` is your new component's name. - -This will create a directory in `/src/` that will contain templates for all necessary files to start developing the component: -``` -MyComponent -├── index.jsx -├── README.md -├── MyComponent.scss -├── _variables.scss -└── MyComponent.test.jsx -``` - -The script will also automatically export your component from Paragon. - -#### 3. Start developing - -`/src/MyComponent/index.jsx` is where your component lives, the file is created with the following template, edit it to implement your own component. - -``` jsx -import React from 'react'; -import PropTypes from 'prop-types'; -import classNames from 'classnames'; - -const MyComponent = React.forwardRef(({ className, children }, ref) => ( -
- {children} -
-)); - -MyComponent.defaultProps = { - className: undefined, -}; - -MyComponent.propTypes = { - /** A class name to append to the base element. */ - className: PropTypes.string, - /** Specifies contents of the component. */ - children: PropTypes.node.isRequired, -}; - -export default MyComponent; - -``` - -#### 4. (Optional) Add styles to your component. +## Internationalization -If your component requires additional styling (which most likely is the case), edit created SCSS style sheet in your -component's directory `/src/MyComponent/MyComponent.scss` which by default contains an empty class for your component. - -If you wish to use SASS variables (which is the preferred way of styling the components since values can be -easily overridden and customized by the consumers of Paragon), add them in `/src/MyComponent/_variables.scss` (this file should contain all variables specific to your component). -This way the variables will also get automatically picked up by documentation site and displayed on your component's page. - -**Please note that you need to follow [Paragon's CSS styling conventions](docs/decisions/0012-css-styling-conventions).** - -#### 5. Document your component +Paragon supports internationalization for its components out of the box with the support of [react-intl](https://formatjs.io/docs/react-intl/). You may view translated strings for each component on the documentation website by switching languages in the settings. -The documentation for your component lives in `src/MyComponent/README.md`. The documentation site scans this directory for markdown or mdx files to create pages. By default, the file is created with following content: - -```` md ---- -title: 'MyComponent' -type: 'component' -components: -- MyComponent -status: 'New' -designStatus: 'Done' -devStatus: 'Done' -notes: | - Something special about this component ---- - -Describe your component here and give usage examples. - -### Basic Usage - -```jsx live - - Hello! - -``` - -```` +Due to Paragon's dependence on ``react-intl``, that means that your whole app needs to be wrapped in its provider, e.g.: -##### Some notes on the format above: - -The top part of the markdown file is known as `frontmatter`. This metadata with consumed by the documentation site to control the title of the page and the doc site navigation. -- **title** controls the page title of the generated page -- **components** is a list of react components by displayName. This usually matches the name you define the component as in code. (In our example so far it is MyComponent). Components added to this list will be scanned by react-docgen for code comments and a props api table will be rendered at the bottom of the page. -- **categories** is a list of categories where this page will appear the documentation site menu. -- **status**, **designStatus**, **devStatus**, and **notes** appear in the http://localhost:8000/status page. - -JSX code blocks in the markdown file can be made interactive with the live attribute. All paragon components and icons are in scope. (Note: the scope of this code block is controlled by `www/components/CodeBlock.jsx`). - -#### 6. Navigate to your component on the doc site and start building - -Visit the documentation at [http://localhost:8000](http://localhost:8000) and navigate to see your README.md powered page and workbench. Changes to the README.md file will auto refresh the page. - -### Internationalization - -Paragon supports internationalization for its components out of the box with the support of [react-intl](https://formatjs.io/docs/react-intl/). You can view translated strings for each component on the docs site after switching language on a settings tab. - -#### For consumers - -Since we are using ``react-intl`` that means that your whole app needs to be wrapped in its context, e.g. ```javascript import { IntlProvider } from 'react-intl'; import { messages as paragonMessages } from '@edx/paragon'; @@ -204,8 +81,7 @@ Since we are using ``react-intl`` that means that your whole app needs to be wra ) ``` -Note that if you are using ``@edx/frontend-platform``'s ``AppProvider`` component you don't need a separate context, -you would only need to add Paragon's messages like this +Note that if you are using ``@edx/frontend-platform``'s ``AppProvider`` component, you don't need a separate context as `IntlProvider` is already included; you would only need to add Paragon's i18n messages like this: ```javascript import { APP_READY, subscribe, initialize } from '@edx/frontend-platform'; @@ -235,7 +111,46 @@ you would only need to add Paragon's messages like this }); ``` -#### For developers +## Contributing + +Please refer to the ["How to Contribute"](https://openedx.org/r/how-to-contribute) documentation and [Code of Conduct](https://openedx.org/code-of-conduct/) from Open edX. + +The Paragon Working Group accepts bug fixes, new features, documentation, and security patches. You may find open issues [here](https://github.com/openedx/paragon/issues) or by visiting the Paragon Working Group [project board](https://github.com/orgs/openedx/projects/43/views/15). + +If you'd like to contribute a new component or update an existing component, please consider reaching out to the Paragon Working Group via the channels [described above](#getting-help) to propose your changes. + +The Paragon Working Group looks forward to your contributions! 💎 + +### Development + +#### Developing locally against a micro-frontend (MFE) + +If you want to test the changes with local MFE setup, you need to create a "module.config.js" file in your MFE's directory containing local module overrides. After that the webpack build for your application will automatically pick your local version of Paragon and use it. The example of module.config.js file looks like this (for more details about module.config.js, refer to the [frontend-build documentation](https://github.com/openedx/frontend-build#local-module-configuration-for-webpack).): + +```javascript +module.exports = { + /* + Modules you want to use from local source code. Adding a module here means that when + your MFE runs its build, it'll resolve the source from peer directories of the app. + + moduleName: the name you use to import code from the module. + dir: The relative path to the module's source code. + dist: The sub-directory of the source code where it puts its build artifact. Often "dist". + */ + localModules: [ + { moduleName: '@edx/paragon/scss/core', dir: '../src/paragon', dist: 'scss/core' }, + { moduleName: '@edx/paragon/icons', dir: '../src/paragon', dist: 'icons' }, + // Note that using dist: 'dist' will require you to run 'npm build' in Paragon + // to add local changes to the 'dist' directory, so that they can be picked up by the MFE. + // To avoid doing that you can use dist: 'src' to get any local changes hot reloaded on save in the MFE. + { moduleName: '@edx/paragon', dir: '../src/paragon', dist: 'dist' }, + ], +}; +``` + +Then, when importing Paragon's core SCSS in your MFE the import needs to begin with a tilde `~` so that path to your local Paragon repository gets resolved correctly: `@import "~@edx/paragon/scss/core";` + +#### Internationalization When developing a new component you should generally follow three rules: 1. The component should not have **any** hardcoded strings as it would be impossible for consumers to translate it @@ -319,32 +234,124 @@ When developing a new component you should generally follow three rules: }; ``` -### Developing locally against a micro-frontend (MFE) +#### Adding a new component -If you want to test the changes with local MFE setup, you need to create a "module.config.js" file in your MFE's directory containing local module overrides. After that the webpack build for your application will automatically pick your local version of Paragon and use it. The example of module.config.js file looks like this (for more details about module.config.js, refer to the [frontend-build documentation](https://github.com/openedx/frontend-build#local-module-configuration-for-webpack).): +##### 1. Start the documentation site development server -```javascript -module.exports = { - /* - Modules you want to use from local source code. Adding a module here means that when - your MFE runs its build, it'll resolve the source from peer directories of the app. +The Paragon documentation site serves both as documentation and as a workbench to create your component within. To see your component in action, you need to run the documentation site locally. (Note you need to install dependencies both in the project root and the `www` directory) - moduleName: the name you use to import code from the module. - dir: The relative path to the module's source code. - dist: The sub-directory of the source code where it puts its build artifact. Often "dist". - */ - localModules: [ - { moduleName: '@edx/paragon/scss/core', dir: '../src/paragon', dist: 'scss/core' }, - { moduleName: '@edx/paragon/icons', dir: '../src/paragon', dist: 'icons' }, - // Note that using dist: 'dist' will require you to run 'npm build' in Paragon - // to add local changes to the 'dist' directory, so that they can be picked up by the MFE. - // To avoid doing that you can use dist: 'src' to get any local changes hot reloaded on save in the MFE. - { moduleName: '@edx/paragon', dir: '../src/paragon', dist: 'dist' }, - ], +``` +npm run install-all +cd www +npm start +``` + +##### 2. Create new component + +To create new component run + +``` +npm run generate-component MyComponent +``` + +where `MyComponent` is your new component's name. + +This will create a directory in `/src/` that will contain templates for all necessary files to start developing the component: +``` +MyComponent +├── index.jsx +├── README.md +├── MyComponent.scss +├── _variables.scss +└── MyComponent.test.jsx +``` + +The script will also automatically export your component from Paragon. + +##### 3. Start developing + +`/src/MyComponent/index.jsx` is where your component lives, the file is created with the following template, edit it to implement your own component. + +``` jsx +import React from 'react'; +import PropTypes from 'prop-types'; +import classNames from 'classnames'; + +const MyComponent = React.forwardRef(({ className, children }, ref) => ( +
+ {children} +
+)); + +MyComponent.defaultProps = { + className: undefined, }; + +MyComponent.propTypes = { + /** A class name to append to the base element. */ + className: PropTypes.string, + /** Specifies contents of the component. */ + children: PropTypes.node.isRequired, +}; + +export default MyComponent; + ``` -Then, when importing Paragon's core SCSS in your MFE the import needs to begin with a tilde `~` so that path to your local Paragon repository gets resolved correctly: `@import "~@edx/paragon/scss/core";` +##### 4. (Optional) Add styles to your component. + +If your component requires additional styling (which most likely is the case), edit created SCSS style sheet in your +component's directory `/src/MyComponent/MyComponent.scss` which by default contains an empty class for your component. + +If you wish to use SASS variables (which is the preferred way of styling the components since values can be +easily overridden and customized by the consumers of Paragon), add them in `/src/MyComponent/_variables.scss` (this file should contain all variables specific to your component). +This way the variables will also get automatically picked up by documentation site and displayed on your component's page. + +**Please note that you need to follow [Paragon's CSS styling conventions](docs/decisions/0012-css-styling-conventions).** + +##### 5. Document your component + +The documentation for your component lives in `src/MyComponent/README.md`. The documentation site scans this directory for markdown or mdx files to create pages. By default, the file is created with following content: + +```` md +--- +title: 'MyComponent' +type: 'component' +components: +- MyComponent +status: 'New' +designStatus: 'Done' +devStatus: 'Done' +notes: | + Something special about this component +--- + +Describe your component here and give usage examples. + +### Basic Usage + +```jsx live + + Hello! + +``` + +```` + +Some notes on the format above: + +The top part of the markdown file is known as `frontmatter`. This metadata with consumed by the documentation site to control the title of the page and the doc site navigation. + +- **title** controls the page title of the generated page +- **components** is a list of react components by displayName. This usually matches the name you define the component as in code. (In our example so far it is MyComponent). Components added to this list will be scanned by react-docgen for code comments and a props api table will be rendered at the bottom of the page. +- **categories** is a list of categories where this page will appear the documentation site menu. +- **status**, **designStatus**, **devStatus**, and **notes** appear in the http://localhost:8000/status page. + +JSX code blocks in the markdown file can be made interactive with the live attribute. All paragon components and icons are in scope. (Note: the scope of this code block is controlled by `www/components/CodeBlock.jsx`). + +##### 6. Navigate to your component on the doc site and start building + +Visit the documentation at [http://localhost:8000](http://localhost:8000) and navigate to see your README.md powered page and workbench. Changes to the README.md file will auto refresh the page. ### ESLint