{"id":20856475,"url":"https://github.com/cityofnewyork/patterns-cli","last_synced_at":"2025-05-12T07:32:05.191Z","repository":{"id":39220433,"uuid":"173318299","full_name":"CityOfNewYork/patterns-cli","owner":"CityOfNewYork","description":"A front-end CLI for building and managing design pattern libraries. Maintained by @NYCOpportunity","archived":false,"fork":false,"pushed_at":"2023-03-05T17:08:05.000Z","size":2091,"stargazers_count":15,"open_issues_count":16,"forks_count":1,"subscribers_count":16,"default_branch":"main","last_synced_at":"2025-04-17T04:04:31.403Z","etag":null,"topics":["civic","cli","dart-sass","design-systems","design-tokens","es-modules","eslint","nycopportunity","patterns","patterns-cli","postcss","pttrn","sass","slm-lang","stylelint","svg-sprite","svgo","svgs","tailwindcss","templates"],"latest_commit_sha":null,"homepage":"https://nycopportunity.github.io/patterns-framework/","language":"JavaScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"gpl-3.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/CityOfNewYork.png","metadata":{"files":{"readme":"readme.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2019-03-01T14:45:51.000Z","updated_at":"2025-02-26T13:37:04.000Z","dependencies_parsed_at":"2024-06-21T05:54:34.181Z","dependency_job_id":null,"html_url":"https://github.com/CityOfNewYork/patterns-cli","commit_stats":null,"previous_names":["cityofnewyork/nyco-patterns-framework"],"tags_count":71,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/CityOfNewYork%2Fpatterns-cli","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/CityOfNewYork%2Fpatterns-cli/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/CityOfNewYork%2Fpatterns-cli/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/CityOfNewYork%2Fpatterns-cli/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/CityOfNewYork","download_url":"https://codeload.github.com/CityOfNewYork/patterns-cli/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":253695257,"owners_count":21948852,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["civic","cli","dart-sass","design-systems","design-tokens","es-modules","eslint","nycopportunity","patterns","patterns-cli","postcss","pttrn","sass","slm-lang","stylelint","svg-sprite","svgo","svgs","tailwindcss","templates"],"created_at":"2024-11-18T04:32:00.779Z","updated_at":"2025-05-12T07:32:04.575Z","avatar_url":"https://github.com/CityOfNewYork.png","language":"JavaScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Patterns CLI\n\n### Make, develop, and publish!\n\nA front-end CLI for managing static design pattern libraries. Created and maintained by [**@NYCOpportunity**](https://github.com/NYCOpportunity). For examples of what the CLI can create and manage, look at our existing pattern libraries; [Working NYC Patterns](https://cityofnewyork.github.io/nyco-wnyc-patterns), [NYCO Patterns](https://nycopatterns.cityofnewyork.us), [ACCESS NYC Patterns](https://accesspatterns.cityofnewyork.us), and [Growing Up NYC Patterns](https://github.com/NYCOpportunity/growingupnyc-patterns). Essentially, the CLI is a static generator with the following extra features.\n\n* 📦 Creates and organizes component libraries using a [design system methodology](#design-system-methodology).\n\n* 🌈 Manages [design tokens](#design-tokens) in JSON format amd works well with [Tailwindcss](https://tailwindcss.com/).\n\n* ⚛️ Agnostic of existing JavaScript Frameworks. Use it to manage a customized component library or extend the default module templates to build out Vanilla ES, [React](https://reactjs.org/), [Vue.js](https://vuejs.org/), or [Svelte](https://svelte.dev/) components.\n\n* 🚀 Scripts for publishing a pattern library to [npm](https://www.npmjs.com/) for open sourcing and integration into multiple digital products.\n\n* 🤸 Ensures accessibility during development by linting rendered HTML with [Pa11y](https://pa11y.org/).\n\n* ⚙️ Highly configurable and pluggable for a particular project's needs.\n\n#### Background\n\nThe Patterns CLI is the core developer module of the [NYCO User Interface (UI) Patterns Framework](https://nycopportunity.github.io/patterns-framework/). The project started to make building and documenting accessible, CSS–first, and framework–free pattern libraries quick, easy, and fun, doing so without task runners and a minimal amount of JavaScript to tie it all together. It does this very well, and over time it has grown into a build system of its own, so acknowledging this as an in-house alternative is essential. Other pattern build systems with more extensive community support also exist and are well worth a look. These include [Storybook.js](https://storybook.js.org/), [Fractal](https://fractal.build/), [Pattern Lab](https://patternlab.io/), and possibly more.\n\n## I want to\n\n* [Browse the features](#features).\n\n* [View the documentation](#contents).\n\n* [Quick start a new project](#scaffold-command). Run the following command.\n\n```shell\n$ npx @nycopportunity/pttrn scaffold \u0026\u0026 npm install\n```\n\nWhen scaffolding is finished run `npm start` to start the development server.\n\n## Features\n\n### ✨ Make module-based patterns\n\nThe CLI has several commands, including `make`, for quickly generating new pattern modules using file templates.\n\n```shell\n$ npx pttrn make component accordion\n\n✨ Created ./src/components/accordion/accordion.slm\n✨ Created ./src/components/accordion/accordion.md\n✨ Created ./src/components/accordion/_accordion.scss\n```\n\nTemplates can be extended to create files to support the framework of your choosing.\n\n### Design System Methodology\n\nAll design pattern source code will be organized into four directories: **Elements**, **Components**, **Objects**, and **Utilities** (by default). The CLI takes care of the organization for you, creating the necessary files based on configurable templates.\n\n```\n📂 src\n├ 📁 elements\n├ 📂 components\n  └ 📂 accordion\n    ├ accordion.slm   - Markup\n    ├ accordion.js    - JavaScript\n    ├ _accordion.scss - Styling\n    ├ accordion.md    - Documentation\n    └ readme.md       - Developer Usage\n├ 📁 objects\n└ 📁 utilities\n```\n\n### 🔌 Demonstrate and document markup once\n\nWrite dynamic and reusable markup used to create live demonstrations and document markup once using [slm-lang](https://github.com/slm-lang) (an HTML template language inspired by Pug).\n\n```pug\n- this.accordion = {}\n- this.accordion.id = this.createId()\n- this.accordion.active = true\n\n- if (typeof accordion !== 'undefined')\n  - this.accordion = Object.assign(this.accordion, accordion);\n\narticle class='c-accordion'\n  header class='c-accordion__header'\n    /! { @data-js        \"accordion\" initalizes the Accordion toggle }\n    /! { @aria-controls  Targets the Accordion body }\n    /! { @aria-expanded  Indicates if the Accordion body is open or not }\n    button class='c-accordion__toggle w-full text-start print:hidden ${this.accordion.active ? 'active' : ''}' data-js='accordion' aria-controls='aria-c-${this.accordion.id}' aria-expanded='${this.accordion.active.toString()}'\n      span class='c-accordion__heading mt-0' id='aria-lb-${this.accordion.id}'\n        span = this.accordion.title\n\n      span class='c-accordion__toggle-active'\n        svg class='icon-wnyc-ui' aria-hidden='true'\n          use xlink:href='#icon-wnyc-ui-chevron-down'\n\n        span class='sr-only' hide this list\n\n      span class='c-accordion__toggle-inactive'\n        svg class='icon-wnyc-ui' aria-hidden='true'\n          use xlink:href='#icon-wnyc-ui-chevron-up'\n\n        span class='sr-only' show this list\n\n  /! { @id               Target of the Accordion toggle. Must match the \"aria-controls\" attribute of the toggling button }\n  /! { @role             Indicates an area of significance }\n  /! { @aria-labelledby  Associates the Accordion body with the header text }\n  /! { @aria-hidden      Indicates if the Accordion body is open or not }\n  div id='aria-c-${this.accordion.id}' role='region' class='c-accordion__body bg-scale-3 print:active hidden:overflow animated ${this.accordion.active ? 'active' : 'hidden'}' aria-labelledby='aria-lb-${this.accordion.id}' aria-hidden='${this.accordion.active ? 'false' : 'true'}'\n    div class='c-accordion__padding'\n      = this.accordion.body\n```\n\n### 💅 Style using [Dart Sass](https://sass-lang.com/dart-sass)\n\nDart Sass has many perks such as module-based dependencies. Additionally, CSS post-processing can be customized with [PostCSS](https://postcss.org/) plugins. [LibSass](https://sass-lang.com/libsass) is also supported if desired.\n\n```scss\n// Dependencies\n@use 'config/dimensions';\n@use 'config/media';\n@use 'config/interaction';\n\n// Declarations\n.c-accordion {\n  margin: 0 0 dimensions.$spacing-base;\n}\n\n.c-accordion__header {\n  padding: dimensions.$spacing-base;\n}\n\n.c-accordion__heading {\n  flex: 1;\n  font-weight: bold;\n  margin: 0;\n}\n\n.c-accordion__toggle {\n  text-decoration: underline;\n  display: inline-flex;\n  align-items: center;\n\n  * {\n    @include interaction.disable-pointer-events\n  }\n}\n\n.c-accordion__toggle-active,\n.c-accordion__toggle-inactive {\n  align-items: center;\n}\n\n.c-accordion__toggle-active {\n  display: none;\n  visibility: hidden;\n\n  .c-accordion__toggle.active \u0026 {\n    @include interaction.disable-pointer-events;\n    display: inline-flex;\n    visibility: visible\n  }\n}\n\n.c-accordion__toggle-inactive {\n  @include interaction.disable-pointer-events;\n  display: inline-flex;\n  visibility: visible;\n\n  .c-accordion__toggle.active \u0026 {\n    display: none;\n    visibility: hidden\n  }\n}\n\n.c-accordion__padding {\n  padding: dimensions.$spacing-base\n}\n\n.c-accordion__padding \u003e *:last-child {\n  margin-bottom: 0\n}\n```\n\n### 🤸 Lint for accessibility issues using Pa11y\n\n[Pa11y CI](https://github.com/pa11y/pa11y-ci) will run tests and provide suggestions for accessibility compliance.\n\n```shell\n⏳ Running Pa11y CI on ./dist/web-share.html\n🤸 Pa11y suggestions for ./dist/web-share.html\n\u003cpre\u003e\u003ccode\u003eimport WebShare from '@ny...\u003c/pre\u003e\naxe     error   Ensure that scrollable region has keyboard access (https://dequeuniversity.com/rules/axe/3.5/scrollable-region-focusable?application=axeAPI)  scrollable-region-focusable\n\n⏳ Running Pa11y CI on ./dist/utility.html\n🤸 Pa11y suggestions for ./dist/utility.html\n\u003ca class=\"ms-3 btn btn-secondary btn-link\" href=\"#next-steps\"\u003eNext steps\u003c/a\u003e\nhtmlcs  error   This link points to a named anchor \"next-steps\" within the document, but no anchor exists with that name.  G124.NoSuchID\n\n⏳ Running Pa11y CI on ./dist/text-controller.html\n✨ No Pa11y suggestions for ./dist/text-controller.html\n⏳ Running Pa11y CI on ./dist/tables.html\n🤸 Pa11y suggestions for ./dist/tables.html\n\u003ctable class=\"table-headers-first-column\"\u003e\u003cthead\u003e...\u003c/table\u003e\nhtmlcs  error   The relationship between td elements and their associated th elements is not defined. Use either the scope attribute on th elements, or the headers attribute on td elements.  H63\n\n\u003ctable class=\"table-headers-sticky\"\u003e\u003cthead\u003e...\u003c/table\u003e\nhtmlcs  error   The relationship between td elements and their associated th elements is not defined. Use either the scope attribute on th elements, or the headers attribute on td elements.  H63\n\n⏳ Running Pa11y CI on ./dist/selects.html\n🤸 Pa11y suggestions for ./dist/selects.html\n\u003cselect id=\"ba1a47a76758b\" name=\"\" required=\"true\"\u003e\u003coption sele...\u003c/select\u003e\naxe     error   Form elements must have labels (https://dequeuniversity.com/rules/axe/3.5/label?application=axeAPI)  label\n\n\u003cselect id=\"ba1a47a76758b\" name=\"\" required=\"true\"\u003e\u003coption sele...\u003c/select\u003e\nhtmlcs  error   This select element does not have a name available to an accessibility API. Valid names are: label element, title undefined, aria-label undefined, aria-labelledby undefined.  WCAG2AA.Principle4.Guideline4_1.4_1_2.H91.Select.Name\n\n\u003cselect id=\"ba1a47a76758b\" name=\"\" required=\"true\"\u003e\u003coption sele...\u003c/select\u003e\nhtmlcs  error   This form field should be labelled in some way. Use the label element (either with a \"for\" attribute or wrapped around the form field), or \"title\", \"aria-label\" or \"aria-labelledby\" attributes as appropriate.  WCAG2AA.Principle1.Guideline1_3.1_3_1.F68\n```\n\n### 🗞 Script using ES module syntax.\n\nLibrary scripts are bundled using [rollup.js](https://rollupjs.org/guide/en/). Use the [library of utility ES modules](https://github.com/CityOfNewYork/patterns-scripts) to help keep scripting DRY.\n\n```javascript\n'use strict';\n\nimport Toggle from '@nycopportunity/pttrn-scripts/src/toggle/toggle';\n\n/**\n * The Accordion module\n *\n * @class\n */\nclass Accordion {\n  /**\n   * @constructor\n   *\n   * @return  {object}  The instantiated accordion component\n   */\n  constructor() {\n    this.toggle = new Toggle({\n      selector: Accordion.selector\n    });\n\n    return this;\n  }\n}\n\n/** @type {String} The dom selector for the module */\nAccordion.selector = '[data-js*=\"accordion\"]';\n\nexport default Accordion;\n```\n\n### ⚫ Manage design tokens in JavaScript\n\n[Design Tokens](#design-tokens) are compiled to a Sass map and can be imported into a [Tailwindcss](https://tailwindcss.com/docs/installation#create-your-tailwind-config-file) config for creating a single source between JavaScript, Sass files, and CSS utilities.\n\n```javascript\nmodule.exports = {\n  'output': '\"./src/config/_tokens.scss\"',\n  'border': {\n    'width': '3px',\n    'style': 'solid',\n    'radius': '16px'\n  },\n  'color': {\n    'white': '#FFF',\n    'blue': '#284CCA',\n    'red': '#FC5D52',\n    'gray': '#E6E8EC'\n  },\n  'font-family': {\n    'system': ['-apple-system', 'BlinkMacSystemFont', '\"Segoe UI\"', 'Roboto', 'Oxygen-Sans', 'Ubuntu', 'Cantarell', '\"Helvetica Neue\"', 'sans-serif'],\n    'monospace': 'monospace'\n  },\n  'font': {\n    'body': 'system',\n    'pre': 'monospace'\n  },\n  'font-weight': {\n    'body': 'normal',\n    'pre': 'normal'\n  },\n  'font-style': {\n    'body': 'normal',\n    'pre': 'normal'\n  },\n  'font-size': {\n    'body': '1em',\n    'pre': '0.9em'\n  },\n  'line-height': {\n    'body': '1.2',\n    'pre': '1.5'\n  },\n  'grid': '8px', // 8px grid system\n  'typography': {\n    'small': '16px',\n    'mobile': '18px',\n    'tablet': '20px',\n    'desktop': '22px'\n  }\n};\n```\n\n### 🗜️ Optimize and generate SVG sprites\n\nUses [svgo](https://github.com/svg/svgo) to optimize individual svgs and [svgstore-cli](https://github.com/svgstore/svgstore-cli) to concatenate an SVG sprite for rendering icons and vector graphics.\n\n```shell\n🗜️  Svgs in ./src/svg/shape-c.svg out ./dist/svg/pttrn-shape-c.svg\n🗜️  Svgs in ./src/svg/shape-b.svg out ./dist/svg/pttrn-shape-b.svg\n🗜️  Svgs in ./src/svg/shape-a.svg out ./dist/svg/pttrn-shape-a.svg\n🗜️  Svgs in ./src/svg/select-chevrons.svg out ./dist/svg/pttrn-select-chevrons.svg\n🗜️  Svgs in ./src/svg/option-radio.svg out ./dist/svg/pttrn-option-radio.svg\n🗜️  Svgs in ./src/svg/option-checkbox.svg out ./dist/svg/pttrn-option-checkbox.svg\n🗜️  Svgs in ./src/svg/logo-standard.svg out ./dist/svg/pttrn-logo-standard.svg\n🗜️  Svgs in ./src/svg/logo-stacked.svg out ./dist/svg/pttrn-logo-stacked.svg\n🗜️  Svgs in ./src/svg/logo-partnership.svg out ./dist/svg/pttrn-logo-partnership.svg\n🗜️  Svgs in ./src/svg/logo-nyc.svg out ./dist/svg/pttrn-logo-nyc.svg\n🗜️  Svgs in ./src/svg/logo-google-translate.svg out ./dist/svg/pttrn-logo-google-translate.svg\n📦 Svgs sprite written to ./dist/svg/svgs.svg\n✨ Svgs finished\n```\n\n### 👀 Watch and serve assets\n\nWatch for file changes using [Chokidar](https://github.com/paulmillr/chokidar) and serve distributed static assets to a local development environment using [Express.js](https://expressjs.com/).\n\n```shell\n$ npm start\n\n\u003e @nycopportunity/pttrn-starter@0.1.0 start @nycopportunity/pttrn-starter\n\u003e cross-env NODE_ENV=development cross-env PORT=7070 concurrently \"pttrn default -w\" \"pttrn serve -w\" -p \"none\"\n\n👀 Serve watching ./dist/**/*.html, ./dist/css/*.css, ./dist/js/*.js\n🤓 Serving ./dist/ to http://localhost:7070\n👀 Slm watching ./config/slm.js, ./src/**/*.slm, ./src/**/*.md\n👀 Svgs watching ./src/svg/**/*.svg\n👀 Rollup watching ./config/rollup.js, ./src/**/*.js\n👀 Styles watching ./src/**/*.scss, ./config/tokens.js, ./config/tailwindcss.js\n```\n\n### No config or custom build\n\nEach major feature uses a [configuration file](config) for adjusting the settings of every CLI script. Additionally, the package can be extended with other npm packages and custom [npm scripts](https://docs.npmjs.com/misc/scripts).\n\n```\n├ 📂 config         - Configuration directory\n  ├ 📂 make          - Templates for pattern files created by the make command\n    ├ style.scss       - Sass Stylesheet template\n    ├ markup.slm       - Markup template\n    ├ markdown.md      - Usage, design specs, and other documentation\n    ├ config.scss      - Sass variable and mixin storage\n    ├ script.js        - JavaScript module template\n    ├ readme.md        - Technical documentation such as JavaScript usage or installation\n    └ view.slm         - View template for displaying the demonstration and documentation\n  ├ make.js          - Make command settings\n  ├ alerts.js        - Configure the icons and colors of alerts in the output\n  ├ global.js        - Global paths and directories\n  ├ lint.js          - ESLint and Style Lint\n  ├ pa11y.js         - Settings for Pa11y linting\n  ├ postcss.js       - PostCSS settings and plugins\n  ├ publish.js       - Publish settings\n  ├ rollup.js        - Rollup.js settings\n  ├ sass.js          - Sass and Sass Module settings\n  ├ slm.js           - slm-lang templating system settings\n  ├ svgs.js          - Svg sprite settings for svgo and svgstore\n  ├ tailwindcss.js   - Tailwindcss config file\n  └ tokens.js        - Design tokens and json-to-scss settings\n├ 📁 dist          - Static distribution directory\n└ 📁 src           - Source directory\n```\n\n## Contents\n\n* [Installation](#installation)\n* [Guide: Start from scratch](#start-from-scratch)\n  * [`make` command](#make-command)\n  * [The file specs](#the-file-specs)\n  * [Styles](#styles)\n  * [Scripts](#scripts)\n  * [Views](#views)\n  * [Serve](#serve)\n* [Guide: `scaffold` command](#scaffold-command)\n* [Guide: `start` command](#start-command)\n* [Guide: `publish` command](#publish-command)\n* [Demo Source](#demo-source)\n* [CLI](#cli)\n  * [Executing the binary](#executing-the-binary)\n  * [Commands](#commands): [`default`](#default), [`styles`](#styles), [`tokens`](#tokens), [`sass`](#sass), [`postcss`](#postCSS), [`rollup`](#rollup), [`lint`](#lint), [`slm`](#slm), [`pa11y`](#pa11y), [`svgs`](#svgs), [`scaffold`](#scaffold), [`make`](#make), [`serve`](#serve), [`publish`](#publish)\n  * [Flags](#flags)\n  * [Alerts](#alerts)\n  * [Custom Commands](#custom-commands)\n  * [NPM Scripts](#npm-scripts)\n* [Guide: Adding Tailwindcss](#adding-tailwindcss)\n* [Guide: Creating a new `make` command template](#creating-a-new-make-command-template)\n* [Optional dependencies](#optional-dependencies)\n* [Supporting Packages](#supporting-packages)\n\n## Installation\n\n**$1** Install as a normal dependency in a project.\n\n```shell\n$ npm install @nycopportunity/pttrn\n```\n\nIf you need to start a new project you can run `npm init -y` before installing.\n\n## Start from scratch\n\n[... or quickly scaffold a new project](#scaffold-command)\n\n### `make` command\n\n**$2** Make a pattern by running `npx pttrn make {{ element/component/object/utility }} {{ pattern }}`\n\n```shell\n$ npx pttrn make component accordion\n\n✨ Created ./src/components/accordion/accordion.slm\n✨ Created ./src/components/accordion/accordion.md\n✨ Created ./src/components/accordion/_accordion.scss\n\n💅 Include the accordion stylesheet in your main Sass entry point. To create an independent distribution (optional) add the accordion stylesheet to your Sass configuration.\n\n❓ Make a config file for accordion? y/n ↵\n```\n\nWhat just happened?\n\n1. The make script has made required files for styling and documenting a component for you based on a few templates included with the Framework;\n1. reminded you to add the stylesheet module to the global default stylesheet so it's compiled accordingly;\n1. and prompted to create any of the other optional files specific to the accordion. If you decide not to make any of these files initially, they can be made by rerunning the `npx pttrn make component accordion {{ file }}` command. For the sake of this demonstration answer \"yes\" (y) to all of the questions.\n\n```shell\n✨ ./src/config/_accordion.scss was made.\n\n❓ Make a view file for accordion? y/n ↵ y\n✨ ./src/views/accordion.slm was made.\n\n❓ Make a script file for accordion? y/n ↵ y\n✨ ./src/components/accordion/accordion.js was made.\n\n🌈 Import the accordion script into your main JavaScript entry point file and create a public function for it in the default class. To create an independent distribution (optional) add the accordion script to your Rollup configuration.\n\n❓ Make a readme file for accordion? y/n ↵ y\n✨ ./src/components/accordion/readme.md was made.\n```\n\n### The file specs\n\n* **.slm** - files are used to define markup of the component using [slm-lang](https://github.com/slm-lang) that has a syntax inspired by Pug. It is also the HTML template language for all views in a Patterns Framework project\n* **.md** - files are markdown files used to store the documentation of the pattern. Here you would describe types, variations, use cases, etc\n* **.scss** - files are used to style the pattern. All Pattern Framework project styling is module-based\n* **config** - A Sass configuration file where variables, mixins, functions, and other dependencies can be stored\n* **view** - A static view template where the pattern may be demonstrated and documentation can be rendered\n* **script** - An ES Module for JavaScript-enhanced patterns\n* **readme** - A markdown file where the pattern documentation is written\n\n### Styles\n\n**$3** Create the default Sass entry point and add the newly created accordion component stylesheet to it.\n\n```shell\n$ mkdir -p src/scss \u0026\u0026 touch src/scss/default.scss\n$ echo \"@use 'components/accordion/accordion';\" \u003e\u003e src/scss/default.scss\n```\n\nOpen up **./src/components/accordion/_accordion.scss**. It will have the following contents:\n\n```scss\n/**\n * Accordion\n */\n\n// Dependencies\n@use 'config/tokens' as *;\n// @use 'config/accordion';\n\n// Declarations\n.c-accordion { }\n```\n\nEdit the file as you wish (or change the background property to red; `background-color:red`). Be sure to add style attributes to the selector otherwise it will not compile. Then, run the following command:\n\n```\n$ npx pttrn styles\n⚫ Tokens in @pttrn/config/tokens.js out ./src/config/_tokens.scss\n🤓 Lint suggestions for ./src/scss/default.scss\n💅 Sass in ./src/scss/default.scss out ./dist/css/default.css\n💅 PostCSS on ./dist/css/default.css\n✨ Styles finished\n```\n\nWhat just happened?\n\n1. The default tokens configuration from the CLI were compiled to Sass.\n1. StyleLint was run on the default Sass entry point.\n1. The default Sass entry point was compiled to CSS.\n1. PostCSS was run on the default CSS stylesheet.\n\nOpen up **./dist/css/default.css** to see the compiled stylesheet.\n\n### Scripts\n\n**$4** Create the default JavaScript entry point and add the newly created accordion component stylesheet to it.\n\n```shell\n$ mkdir -p src/js \u0026\u0026 touch src/js/default.js\n```\n\nCopy and paste the following into **./src/js/default.js**. This creates the main class that will have an API for the accordion module instantiation.\n\n```javascript\nimport Accordion from '../components/accordion/accordion';\n\nclass Default {\n  constructor() {\n    if (process.env.NODE_ENV != 'production')\n      console.dir('@pttrn Development Mode');\n\n    return this;\n  }\n\n  accordion() {\n    return new Accordion();\n  }\n};\n\nexport default Default;\n```\n\nOpen up **./src/components/accordion/accordion.js**. It will have the following contents:\n\n```javascript\n'use strict';\n\nclass Accordion {\n  /**\n   * @param  {Object}  settings  This could be some configuration options.\n   *                             for the pattern module.\n   * @param  {Object}  data      This could be a set of data that is needed\n   *                             for the pattern module to render.\n   * @constructor\n   */\n  constructor(settings, data) {\n    this.data = data;\n\n    this.settings = settings;\n\n    return this;\n  }\n}\n\n/** @param  {String}  selector  The main selector for the pattern */\nAccordion.selector = '[data-js*=\"accordion\"]';\n\nexport default Accordion;\n```\n\nThe contents of this file are optional, however, using class-based ES modules makes scoping JavaScript-enhanced patterns easier to scope. Edit the file as you wish and run:\n\n```shell\n$ npx pttrn rollup\n🤓 ESLint suggestions for ./src/js/default.js\n6:7     warn    Unexpected console statement. no-console\n🗞️ Rollup in src/js/default.js out dist/js/default.js\n✨ Rollup finished\n```\n\nWhat just happened? The default ES entry point from the CLI was linted and compiled in the iife format for browsers.\n\n### Views\n\n**$5** Create a layout for you pattern views.\n\n```shell\n$ mkdir -p src/slm/layouts \u0026\u0026 touch src/slm/layouts/default.slm\n```\n\nCopy and paste the following **slm** into the **src/slm/layouts/default.slm** file. Edit the file as you wish...\n\n```pug\ndoctype html\nhtml lang='en'\n  head\n    meta charset='utf-8'\n    meta http-equiv='X-UA-Compatible' content='IE=edge'\n    meta name='viewport' content='width=device-width, initial-scale=1'\n\n    title My Patterns\n\n    link rel='stylesheet' href='css/default.css'\n\n  body\n    header\n      h1 My Patterns\n\n    main\n      = content('main')\n\n    footer\n      - let date = new Date();\n      - let opts = {year: 'numeric', month: 'long', day: 'numeric'};\n      p = `Last updated ${date.toLocaleDateString('en-US', opts)}`\n\n    script src='js/default.js'\n\n    javascript:\n      let MyPatterns = new Default();\n\n    = content('scripts')\n\n    / The reload script. This should not be compile during production builds\n    / @source https://www.npmjs.com/package/reload\n    - if this.process.env.NODE_ENV !== 'production'\n      script src='/reload/reload.js'\n```\n\nYou'll need to instantiate the Accordion module in the default entry point class. Open **./src/views/accordion.slm** and add to the scripts block...\n\n```\n\n= content('scripts')\n\n```\n\n... the following script tag...\n\n```\n= content('scripts')\n  javascript:\n    MyPatterns.accordion();\n```\n\n... then run the command:\n\n```shell\n$ npx pttrn slm\n✨ Slm in ./src/views/accordion.slm out ./dist/accordion.html\n⏳ Running Pa11y CI on ./dist/accordion.html\n✨ No Pa11y suggestions for ./dist/accordion.html\n✨ Slm finished\n```\n\nWhat just happened?\n\n1. The Accordion view **slm** file was compiled to HTML.\n1. The command triggered the [Pa11y CI](https://github.com/pa11y/pa11y-ci) to lint the HTML output for accessibility issues. Linting for accessibility issues is a helpful perk of the CLI. No issues here!\n\nOpen up **./dist/accordion.html** to see the compiled accordion view.\n\n### Serve\n\n**$6** Start the development server to see view your work.\n\n```shell\n$ npx pttrn serve\n🤓 Serving ./dist/ to http://localhost:7000\n```\n\nOpen up **http://localhost:7000/accordion** to see the Accordion Component page. Want to make a change? For development purposes we'll want to run the server as well as watch scripts and reload when changes are made. The CLI uses [Concurrently](https://www.npmjs.com/package/concurrently) to run multiple commands so the binary is available to execute in the same way. Combine the `default` command with the `serve` command. Adding the `-w` or `--watch` flag enable change detection on both commands:\n\n```shell\n$ npx concurrently 'pttrn -w' 'pttrn serve -w'\n[1] 👀 Serve watching ./dist/**/*.html, ./dist/**/*.css, ./dist/**/*.js\n[1] 🤓 Serving ./dist/ to http://localhost:7000\n[0] 👀 Slm watching @pttrn/config/slm.js, ./src/**/*.slm, ./src/**/*.md\n[0] 👀 Svgs watching ./src/svg/**/*.svg\n[0] 👀 Rollup watching @pttrn/config/rollup.js, ./src/**/*.js\n[0] 👀 Styles watching ./src/**/*.scss, @pttrn/config/tokens.js, @pttrn/config/tailwindcss.js\n```\n\nWhat just happened? The default watching processes have been announced. Once you save a change to the file Chokidar will detect it and run default style tasks and reload the development server. Make a change to any file such as the **./src/components/accordion/accordion.scss**.\n\n```shell\n[0] 👀 Detected change on ./src/components/accordion/_accordion.scss\n[0] ⚫ Tokens in @pttrn/config/tokens.js out src/config/_tokens.scss\n[0] 🤓 Lint suggestions for ./src/scss/default.scss\n[0] 💅 Sass in ./src/scss/default.scss out dist/css/default.css\n[0] 💅 PostCSS on dist/css/default.css\n[0] 👀 Serve reloading\n```\n\nThe change was detected and the style scripts were run.\n\n[Back to table of contents ^](#contents)\n\n## `scaffold` command\n\nThe `scaffold` command will create a minimal base project with the following:\n\n* A **package.json** file with the recommended [NPM Scripts](#npm-scripts) and this package as a development dependency.\n* CSS only Details Component\n* Configuration files for Tokens, Rollup.js, Sass, and Tailwindcss\n* Simple Sass library\n* Single page static demo site\n\nIf you are running the command in an empty directory or without a **package.json** file, run `npx @nycopportunity/pttrn scaffold`, `npm install`. Once everything is scaffolded you can run `npm start` to start the development server.\n\nIf `@nycopportunity/pttrn` is already installed as a dependency of your project's **package.json** file you can run the following command.\n\n```shell\n$ npx pttrn scaffold\n\n./package.json already exists.\n✨ ./src was made.\n✨ ./src/views was made.\n✨ ./src/views/index.slm was made.\n✨ ./src/utilities was made.\n✨ ./src/utilities/typography was made.\n✨ ./src/utilities/typography/_typography.scss was made.\n✨ ./src/utilities/tailwindcss was made.\n✨ ./src/utilities/tailwindcss/_tailwindcss.scss was made.\n✨ ./src/utilities/padding was made.\n✨ ./src/utilities/padding/_padding.scss was made.\n✨ ./src/utilities/color was made.\n✨ ./src/utilities/color/_color.scss was made.\n✨ ./src/svg was made.\n✨ ./src/svg/a-perfect-heart.svg was made.\n✨ ./src/svg/a-perfect-heart-red.svg was made.\n✨ ./src/slm was made.\n✨ ./src/slm/layouts was made.\n✨ ./src/slm/layouts/default.slm was made.\n✨ ./src/scss was made.\n✨ ./src/scss/default.scss was made.\n✨ ./src/scss/_imports.scss was made.\n✨ ./src/objects was made.\n✨ ./src/js was made.\n✨ ./src/js/default.js was made.\n✨ ./src/elements was made.\n✨ ./src/elements/base was made.\n✨ ./src/elements/base/_base.scss was made.\n✨ ./src/elements/base/_base-first-last.scss was made.\n✨ ./src/config was made.\n✨ ./src/config/_type.scss was made.\n✨ ./src/config/_tokens.scss was made.\n✨ ./src/config/_grid.scss was made.\n✨ ./src/config/_get.scss was made.\n✨ ./src/config/_border.scss was made.\n✨ ./src/components was made.\n✨ ./src/components/details was made.\n✨ ./src/components/details/details.slm was made.\n✨ ./src/components/details/details.md was made.\n✨ ./src/components/details/_details.scss was made.\n✨ ./dist was made.\n✨ ./config was made.\n✨ ./config/tokens.js was made.\n✨ ./config/tailwindcss.js was made.\n✨ ./config/sass.js was made.\n✨ ./config/rollup.js was made.\n```\n\nThen run the following to start the development server and start making.\n\n```shell\n$ npx concurrently 'pttrn -w' 'pttrn serve -w' -p 'none'\n\n👀 Serve watching ./dist/**/*.html, ./dist/**/*.css, ./dist/**/*.js\n🤓 Serving ./dist/ to http://localhost:7000\n👀 Slm watching ./config/slm.js, ./src/**/*.slm, ./src/**/*.md\n👀 Svgs watching ./src/svg/**/*.svg\n👀 Rollup watching ./config/rollup.js, ./src/**/*.js\n👀 Styles watching ./src/**/*.scss, ./config/tokens.js, ./config/tailwindcss.js\n```\n\n[Back to table of contents ^](#contents)\n\n## `start` command\n\nAdd this `start` script in your **package.json** file to create a shorthand for the development server command.\n\n```json\n\"scripts\": {\n  \"start\": \"cross-env NODE_ENV=development cross-env PORT=7000 concurrently \\\"pttrn -w\\\" \\\"pttrn serve -w\\\" -p \\\"none\\\"\"\n}\n```\n\nThis will hook into npm script's default start command for your project. Once this script is in place starting the server and watching files becomes can be done with the following command:\n\n```shell\n$ npm start\n\n\u003e patterns-demo@1.0.0 start patterns-demo\n\u003e cross-env NODE_ENV=development cross-env PORT=7000 concurrently \"pttrn default -w\" \"pttrn serve -w\" -p \"none\"\n\n👀 Serve watching ./dist/**/*.html, ./dist/**/*.css, ./dist/**/*.js\n🤓 Serving ./dist/ to http://localhost:7070\n👀 Slm watching @pttrn/config/slm.js, ./src/**/*.slm, ./src/**/*.md\n👀 Svgs watching ./src/svg/**/*.svg\n👀 Rollup watching @pttrn/config/rollup.js, ./src/**/*.js\n👀 Styles watching ./src/**/*.scss, @pttrn/config/tokens.js, @pttrn/config/tailwind.js\n```\n\n[Back to table of contents ^](#contents)\n\n## `publish` command\n\nBefore publishing, you'll need to have Git initialized for your project. The following lines will do just that and add prevent **/node_modules** from being committed to your project. You can skip these steps if you already have this setup.\n\n```shell\n$ git init\n$ touch .gitignore\n$ echo '/node_modules' \u003e\u003e .gitignore\n```\n\nYou will also need a remote git repository with the repository settings, specifically the URL, are configured in your **package.json** file. Below is an example:\n\n```json\n\"repository\": {\n  \"type\": \"git\",\n  \"url\": \"https://github.com/CityOfNewYork/patterns-demo.git\"\n}\n```\n\nAdding the `version`, `prepublishOnly`, and `publish` scripts in your **package.json** file will create shorthands for quickly versioning and publishing your library on **npmjs.org**.\n\n```json\n\"scripts\": {\n  \"version\": \"pttrn \u0026\u0026 git add .\",\n  \"prepublishOnly\": \"git push \u0026\u0026 git push --tags\",\n  \"publish\": \"cross-env NODE_ENV=production pttrn publish\"\n}\n```\n\nYou will want to start from a reasonable version number in your **package.json** file if starting a new project. Open it up and set the `version` value to `0.0.0`.\n\n```json\n\"version\": \"0.0.0\"\n```\n\nThen you can make the first commit by staging the working directory and committing.\n\n```shell\n$ git add .\n$ git commit -m 'init'\n```\n\nWhen versioning your library you can pass `major`, `minor`, `patch`, or `prerelease` as the argument following [semantic versioning](https://semver.org/).\n\n```shell\n$ npm version minor\nv0.1.0\n\n\u003e patterns-demo@0.1.0 version patterns-demo\n\u003e pttrn default \u0026\u0026 git add .\n\n✨ Slm in ./src/views/accordion.slm out ./dist/accordion.html\n🤸 Running Pa11y CI on ./dist/accordion.html\n🗞️ Rollup in src/js/default.js out dist/js/default.js\n✨ Rollup finished\n⚫ Tokens in @pttrn/config/tokens.js out src/config/_tokens.scss\n🤓 Lint suggestions for ./src/scss/default.scss\n💅 Sass in ./src/scss/default.scss out dist/css/default.css\n🤸 No Pa11y suggestions for ./dist/accordion.html\n✨ Slm finished\n💅 PostCSS on dist/css/default.css\n✨ Styles finished\n```\n\n... then publish to [npm](https://www.npmjs.com/) for integration in other projects...\n\n```shell\n$ npm publish\n\n\u003e patterns-demo@0.1.0 prepublishOnly .\n\u003e git push \u0026\u0026 git push --tags\n\nEnumerating objects: 5, done.\nCounting objects: 100% (5/5), done.\nDelta compression using up to 4 threads\nCompressing objects: 100% (3/3), done.\nWriting objects: 100% (3/3), 379 bytes | 379.00 KiB/s, done.\nTotal 3 (delta 2), reused 0 (delta 0)\nremote: Resolving deltas: 100% (2/2), completed with 2 local objects.\nTo https://github.com/CityOfNewYork/patterns-demo\n   40e700a9..330cbad2  master -\u003e master\nEverything up-to-date\nnpm notice\nnpm notice 📦  patterns-demo@0.1.0\nnpm notice === Tarball Contents ===\nnpm notice 71B   dist/css/default.css\nnpm notice 1.1kB dist/accordion.html\nnpm notice 590B  src/components/accordion/accordion.js\nnpm notice 2.5kB dist/js/default.js\nnpm notice 127B  src/js/default.js\nnpm notice 1.6kB package.json\nnpm notice 87B   src/components/accordion/accordion.md\nnpm notice 99B   readme.md\nnpm notice 585B  src/components/accordion/readme.md\nnpm notice 186B  src/components/accordion/_accordion.scss\nnpm notice 198B  src/config/_accordion.scss\nnpm notice 771B  src/config/_tokens.scss\nnpm notice 40B   src/scss/default.scss\nnpm notice 69B   src/components/accordion/accordion.slm\nnpm notice 421B  src/views/accordion.slm\nnpm notice 843B  src/slm/layouts/default.slm\nnpm notice 232B  dist/svg/svgs.svg\nnpm notice === Tarball Details ===\nnpm notice name:          patterns-demo\nnpm notice version:       0.1.0\nnpm notice package size:  4.6 kB\nnpm notice unpacked size: 9.5 kB\nnpm notice shasum:        47e2e2063c731c9c2b24841cce4288d457cf75c6\nnpm notice integrity:     sha512-gXB4U+AJhlGDo[...]O/CzKHv1LUz4w==\nnpm notice total files:   17\nnpm notice\n\n\u003e patterns-demo@0.1.0 publish .\n\u003e cross-env NODE_ENV=production pttrn publish\n\n🤓 Publishing to origin; https://github.com/CityOfNewYork/patterns-demo.git\n✨ Published to GitHub Pages\n+ patterns-demo@0.1.0\n```\n\n[Back to table of contents ^](#contents)\n\n## Demo Source\n\nThe source code of the demo for the previous guides can be found in the [Patterns Demo repository](https://github.com/CityOfNewYork/patterns-demo).\n\n[Back to table of contents ^](#contents)\n\n\u003c!-- ## Quick Starter\n\nThe [Patterns Starter](https://github.com/CityOfNewYork/patterns-starter) makes it much quicker to initialize a new project.\n\nIn a new project directory run;\n\n```shell\n$ npm init @nycopportunity/pttrn-starter\nNeed to install the following packages:\n  @nycopportunity/create-pttrn-starter\nOk to proceed? (y) y\nInstalling @nycopportunity/pttrn...\nScaffolding the project...\nRunning the initial build...\nYou're all set! Add the recommended npm scripts https://github.com/CityOfNewYork/patterns-cli#npm-scripts to your package.json then run \"npm start\"\n```\n\nYou may need to add a **package.json** file if it wasn't created by running `npm init` then add the [recommended NPM Scripts](#npm-scripts).\n\n[Back to table of contents ^](#contents) --\u003e\n\n## CLI\n\n### Executing the binary\n\nThe key to using the CLI is executing the **.pttrn** binary created in the **node_modules/.bin** directory when you install this module in your project. There are a few ways to execute the local binary;\n\n**$A** Use [npx](https://www.npmjs.com/package/npx) before every `pttrn` command. For most cases, this is the most convenient option as demonstrated in the getting started guide above.\n\n```shell\n$ npx pttrn {{ command }}\n```\n\n**$B** Create an alias to the binary in your shell environment configuration file (such as *.profile* or *.bash_profile*)\n\n```shell\nalias pttrn=\"./node_modules/.bin/pttrn\"\n```\n\nThen running commands can be done like so:\n\n```shell\n$ pttrn {{ command }}\n```\n\n**$C** Or, add an npm script to your *package.json* file. npm will always execute local binaries referenced in the script block.\n\n```json\n\"scripts\": {\n  \"pttrn\": \"pttrn\"\n}\n```\n\nThen running commands can be done like so:\n\n```shell\n$ npm run pttrn {{ command }}\n```\n\n### Commands\n\nThe basic pattern for commands is as follows:\n\n```shell\n$ {{ ENVIRONMENT_VARIABLE }}={{ value }} npx pttrn {{ command }} {{ flag }}\n```\n\n- [`default`](#default)\n- [`styles`](#styles)\n- [`tokens`](#tokens)\n- [`sass`](#sass)\n- [`postcss`](#postCSS)\n- [`rollup`](#rollup)\n- [`lint`](#lint)\n- [`slm`](#slm)\n- [`pa11y`](#pa11y)\n- [`svgs`](#svgs)\n- [`scaffold`](#scaffold)\n- [`make`](#make)\n- [`serve`](#serve)\n- [`publish`](#publish)\n\n### Command Configuration\n\nEvery command is configured with one or a series of JavaScript files inside the [./config](config/) directory. The CLI will check to see if there is a custom configuration file in the local **./config** directory of your project first. If it doesn't exist it will use the [default configuration file in the CLI package](config/). Project configurations can be used to pass in additional and custom options to each package that the CLI uses. Below the packages used and default configurations are described in more detail.\n\n### Command Flags\n\nOptional [flags](#flags) can be passed to the commands for signaling watching and log settings. The log settings are universal so they aren't represented in the command tables below.\n\n### Commands\n\n[Custom commands](#custom-commands) can be defined in the local project **./bin** are described below.\n\n---\n\n#### Default\n\nCommand          | Flags | Configuration | `NODE_ENV`\n-----------------|-------|---------------|-\n`default` or ` ` | `-w`  | n/a           | `production` or `development`\n\nUses [Concurrently](https://github.com/open-cli-tools/concurrently) to synchronously run this series of commands; [`styles`](#styles), [`rollup`](#rollup), [`slm`](#slm), and [`svgs`](#svgs), respectfully. Each command is described in more detail below. The series of commands can be modified by editing the array of commands defined in a custom [./config/default.js](config/default.js) file. Addionally, the options passed to [Concurrently](https://github.com/open-cli-tools/concurrently#concurrentlycommands-options) can also be\n\nBack to [commands ^](#commands) | [table of contents ^](#contents)\n\n---\n\n#### Styles\n\nCommand  | Flags | Configuration | `NODE_ENV`\n---------|-------|---------------|-\n`styles` | `-w`  | n/a           | `production` or `development`\n\nAsynchronously runs this series of commands; [`tokens`](#tokens), [`sass`](#sass), then [`postcss`](#postcss) respectfully and described below.\n\nBack to [commands ^](#commands) | [table of contents ^](#contents)\n\n---\n\n#### Tokens\n\nCommand  | Flags | Configuration\n---------|-------|-\n`tokens` | n/a   | [tokens.js](config/tokens.js)\n\nUses [JSON-TO-SCSS](https://github.com/rlapoele/json-to-scss) to convert design tokens defined in [./config/tokens.js](config/tokens.js) into **./src/config/_tokens.scss**. Tokens can be custom values for your Sass library as well as be values mapped directly to tokens in the Tailwindcss configuration (if used by your project). CSS variables can also be used in the token configuration. Note, other Tailwindcss configuration options, such as variants and modules should be configured in the `tailwindcss` configuration.\n\nSettings for [JSON-TO-SCSS](https://github.com/rlapoele/json-to-scss) are set at the root level of the export and include setting the file output and specific transformation options. Refer to the source for available options.\n\nA custom `tokens` configuration is highly recommended (if not required) for any patterns library that uses the CLI to manage unique design tokens.\n\nBack to [commands ^](#commands) | [table of contents ^](#contents)\n\n---\n\n#### Sass\n\nCommand | Flags | Configuration             | `NODE_ENV`\n--------|-------|---------------------------|-\n`sass`  | `-nl` | [sass.js](config/sass.js) | `production` or `development`\n\nUses [Dart Sass](https://github.com/sass/dart-sass) to compile Sass modules defined in the `sass` configuration into CSS. It will use [Node Sass](https://github.com/sass/node-sass) in place of Dart Sass if it is required in a project's **package.json** file. By default, it will compile the default Sass entry point [./src/scss/default.js](config/scaffold/default.scss). If `NODE_ENV` is set to `development` only the modules with the attribute `devModule: true` will be compiled.\n\nA custom `sass` configuration could be used to add additional Sass modules to compile.\n\nBack to [commands ^](#commands) | [table of contents ^](#contents)\n\n---\n\n#### PostCSS\n\nCommand   | Flags | Configuration\n----------|-------|-\n`postcss` | n/a   | [postcss.js](config/postcss.js) [tailwindcss.js](config/tailwindcss.js)\n\nRuns [PostCSS](https://postcss.org/) on CSS modules defined in the `sass` configuration. [PostCSS plugins](https://github.com/postcss/postcss#plugins) are defined in the configuration. By default, PostCSS is configured to use the plugins [cssnano](https://cssnano.co/) and, if installed in your project, [Tailwindcss](https://tailwindcss.com/). The command will use the [./config/tailwindcss.js](config/tailwindcss.js) file where a custom [Tailwindcss configuration](https://tailwindcss.com/docs/configuration) would live. Learn more about [adding tailwindcss in the guide below](#adding-tailwindcss).\n\nA custom `postcss` configuration could be used to configure PostCSS and add additional plugins needed for a particular project.\n\nA custom `tailwindcss` configuration can easily import values from the configuration of the `tokens` to generate Tailwindcss utilities.\n\nBack to [commands ^](#commands) | [table of contents ^](#contents)\n\n---\n\n#### Rollup\n\nCommand  | Flags      | Configuration                 | `NODE_ENV`\n---------|------------|-------------------------------|-\n`rollup` | `-w` `-nl` | [rollup.js](config/rollup.js) | `production` or `development`\n\nRuns [Rollup.js](https://rollupjs.org/) on an array of ES modules defined in the `rollup` configuration and bundles them into a self-executing function (iife). By default, it will bundle the default JavaScript entry point [./src/js/default.js](config/scaffold/default.js). [Rollup.js plugins](https://github.com/rollup/plugins) included with the default `rollup` configuration include the following:\n\n* [Replace](https://github.com/rollup/plugins/tree/master/packages/replace) for replacing `process.env.NODE_ENV` in scripts with the `NODE_ENV` environment variable passed through the command.\n* [Node Resolve](https://github.com/rollup/plugins/tree/master/packages/node-resolve) for resolving module imports from the **./node_modules** directory.\n\n##### NODE_ENV\n\nThe value `development` will affect the command directly by compiling only the modules with the attribute `devModule: true` (the default entry point module is a development module).\n\nOther ES modules in your library can use the `process.env.NODE_ENV` for things such as logging to the console during development. Say the following line appears in an ES module:\n\n```javascript\nif (process.env.NODE_ENV != 'production')\n  console.dir('A development only log');\n```\n\nIf `NODE_ENV` is set any value other than `production` the statement above will appear in the output like the following:\n\n```javascript\n{\n  console.dir('A development only log');\n}\n```\n\nIf `NODE_ENV` is set to `production` then the statement will not appear at all.\n\n##### Internet Explorer 11 Support\n\nIE 11 is no longer supported. If you absolutely must support it you will need to install and configure [Rollup Plugin Bublé](https://github.com/rollup/plugins/tree/master/packages/buble) or [Rollup Plugin Babel](https://github.com/rollup/plugins/tree/master/packages/babel) and configure them in your project.\n\nA custom `rollup` configuration could be used to add additional output modules to support additional JavaScript environments, such as NodeJS, as well as utilize additional Rollup plugins needed for a particular project.\n\nBack to [commands ^](#commands) | [table of contents ^](#contents)\n\n---\n\n#### Lint\n\nCommand | Flags | Configuration\n--------|-------|-\n`lint`  | n/a   | [lint.js](config/lint.js)\n\nUses [ESLint](https://eslint.org/) and [stylelint](https://stylelint.io/) to lint JavaScript and Sass files in the **./src/** directory. Linting suggestions are logged to the terminal. The default `lint` configuration uses [Google's JavaScript style guide](https://github.com/google/eslint-config-google) and [stylelint's standard config](https://github.com/stylelint/stylelint-config-standard) with a few additional rules.\n\nA custom `lint` configuration could be used to change or extend the linting standards of a project.\n\nBack to [commands ^](#commands) | [table of contents ^](#contents)\n\n---\n\n#### Slm\n\nCommand | Flags      | Configuration                     | `NODE_ENV`\n--------|------------|-----------------------------------|-\n`slm`   | `-w` `-np` | [slm.js](config/slm.js) | `production` or `development`\n\nUses [Slm](https://github.com/slm-lang/slm) to compile Slm pages from the **./src/views/** directory to static HTML pages in the **./dist** directory. Slm files serve as the template language for site documentation and HTML spec for patterns. The output is run through [JS Beautifier](https://github.com/beautify-web/js-beautify) for human-readable markup. The Slm parser is extended with a method that includes Markdown files compiled by [Marked](https://marked.js.org/). The default `slm` configuration passes configuration options to these packages as well as global variables described below.\n\n##### Views\n\nThe default entry-point for Slm views exist in the **./src/views/** directory. Files in this directory will be treated as pages and compiled to the **./dist/** directory. Sub-directories are supported for nested pages. Slm extras, such as partials and layouts, can be placed in the **./src/slm/** directory.\n\n```\n├ 📂 src/            - Source directory\n  ├ 📂 slm/          - Slm extras\n    ├ 📁 partials/\n    └ 📁 layouts/\n  ├ 📂 views/        - Slm views\n    ├ 📂 newsletter  - Sub-directory\n      └ index.slm\n    ├ index.slm      - Homepage\n    ├ accordion.slm  - Accordion demo page\n    └ buttons.slm    - Buttons demo page\n    └ ...\n  └ ...\n```\n\nRunning `npx pttrn slm` would compile the files in the source above to the static distribution described below.\n\n```\n├ 📂 dist/\n  ├ 📂 newsletter\n    └ index.html\n  ├ index.html\n  ├ accordion.html\n  └ buttons.html\n  └ ...\n```\n\n##### Include\n\nThe include method, `this.include()`, accepts a single path argument of a file to be included. It will return the compiled HTML output of the file. Prefixing the method with the single equals sign `=` will escape the returned HTML enabling it to be rendered within a `pre` tag as a code demonstration on the page.\n\n```pug\n= this.include('components/accordion/accordion.slm');\n```\n\nThe double equals sign `==` will prevent HTML escaping and render the HTML as a valid element to be rendered by the browser.\n\n```pug\n== this.include('components/accordion/accordion.slm');\n```\n\nPassing an **.md** file path without escaping will render the markdown file as HTML.\n\n```pug\n== this.include('components/accordion/accordion.md');\n```\n\nThe `slm` command only supports Slm and Markdown files so other file types included by this method will be rendered \"as is.\"\n\nMarkdown files can also include Slm and other Markdown files using the following tag:\n\n```markdown\ninclude{{ path/to/file.slm }}\n```\n\n##### Variables\n\nThe default `slm` configuration passes global variables to use in Slm templates. These include the **package.json**, [./config/global.js](config/global.js), and [./config/tokens.js](config/tokens.js) files. Additionally, the `NODE_ENV` is also passed to templates.\n\n```pug\n= this.package\n= this.global\n= this.tokens\n= this.process.env.NODE_ENV\n```\n\nVariables are also available to Markdown files using the following tag:\n\n```pug\n{{ this.package }}\n{{ this.global }}\n{{ this.tokens }}\n{{ this.process.env.NODE_ENV }}\n```\n\nA custom `slm` configuration could be used to be used to pass additional data and methods to the view templates as well as further configure JS Beautify and Marked.\n\nBack to [commands ^](#commands) | [table of contents ^](#contents)\n\n---\n\n#### Pa11y\n\nCommand | Flags | Configuration\n--------|-------|-\n`pa11y` | n/a   | [pa11y.js](config/pa11y.js)\n\nUses [Pa11y](https://github.com/pa11y/pa11y) to test the static output of HTML files in the **./dist** directory for accessibility issues. Issues are logged to the terminal. The default `pa11y` configuration uses the WCAG AA [accessibility standard](https://github.com/pa11y/pa11y#standard-string), aXe-core, and HTML CodeSniffer as [test runners](https://github.com/pa11y/pa11y#runners), and adds the selector `[data-pa11y=\"disable\"]` to that can be used to [hide elements](https://github.com/pa11y/pa11y#hideelements-string) that shouldn't be tested in the static output.\n\nA custom `pa11y` configuration could be used to enable or disable many of the available [configuration options for Pa11y](https://github.com/pa11y/pa11y#configuration).\n\nBack to [commands ^](#commands) | [table of contents ^](#contents)\n\n---\n\n#### Svgs\n\nCommand | Flags | Configuration\n--------|-------|-\n`svgs`  | `-w`  | [svgs.js](config/svgs.js)\n\nUses [svgo](https://github.com/svg/svgo) to optimize SVGs in the **./src/svg/** directory and saves them in the **./dist/svg** directory. Then, it uses [svgstore](https://github.com/svgstore/svgstore) to create an SVG sprite in the **./dist/svg/svgs.svg** file of all the optimized SVGs. The `svgs` configuration passes svg file name prefix and svg sprite name settings to each package.\n\nA custom `svgs` configuration could be used to add multiple source directories and sprites, modify their svg file prefixes, svg sprite names, and configuration options for [svgo](https://github.com/svg/svgo#what-it-can-do) and [svgstore](https://github.com/svgstore/svgstore#options). Additionally, allows a restrict parameter to limit the svgs that will be compiled from the source directory and included in the sprite.\n\nBack to [commands ^](#commands) | [table of contents ^](#contents)\n\n---\n\n#### Scaffold\n\nCommand    | Flags | Configuration\n-----------|-------|-\n`scaffold` | n/a   | [global.js](config/global.js) [scaffold/*](config/scaffold/)\n\nAs described in the [Scaffold guide](#scaffold-command) above this command will initialize a minimal base project with the following:\n\n* CSS only Details Component\n* Configuration files for Tokens, Rollup.js, Sass, and Tailwindcss\n* Simple Sass library\n* Single page static demo site\n\nThe `scaffold` command relies on the `global.js` configuration that describes the default filesystem and entry points for a project. It also relies on file templates in the [./config/scaffold/](config/scaffold/) directory to source the contents of files described in the system.\n\nA custom `scaffold` configuration could be used to change the output of the starter filesystem and the contents of files for a project.\n\nBack to [commands ^](#commands) | [table of contents ^](#contents)\n\n---\n\n#### Make\n\nCommand | Arguments                  | Flags | Configuration\n--------|----------------------------|-------|-\n`make`  | `type`* `name`* `template` | n/a   | [make.js](config/make.js) [make/*](config/make/)\n\nCreates pattern directories and files using paths and variables defined in the `make` configuration with file contents defined in the [./config/make](config/make/) directory as described in the [`make` command guide](#make-command). It will not permit overwriting pattern files if they already exist.\n\n*denotes required arguments.\n\n##### Arguments\n\n- `type` _required_ - Determines where in the filesystem patterns will be stored. One of; `element`, `component`, `object`, or `utility`\n- `pattern` _required_ - Name of the pattern\n- `template` _optional_ - If included the third argument can be used to create a single template from the [./config/make](config/make/) directory. By default, all files will be made.\n\nA custom `make` configuration could be used to add custom files with predefined templates in the [./config/make](config/make/) directory. The CLI currently supports CSS and ES module-based libraries out-of-the-box, however, with custom make templates, it could be extended to make [Vue.js](https://vuejs.org/), [React](https://reactjs.org/), [Svelte](https://svelte.dev/), or other component type files.\n\nRefer to the guide on [creating a new `make` command template](#creating-a-new-make-command-template) for details.\n\nBack to [commands ^](#commands) | [table of contents ^](#contents)\n\n---\n\n#### Serve\n\nCommand | Flags | Configuration | `PORT`\n--------|-------|---------------|-\n`serve` | `-w`  | n/a           | Any port number (ex; `8080`)\n\nUses [Express](https://expressjs.com/) to serve static files in the **./dist/** directory. By default, it runs on port `7000`. The `serve` command doesn't have a configuration file, however, the port number can be configured through the environment variable `PORT`.\n\nBack to [commands ^](#commands) | [table of contents ^](#contents)\n\n---\n\n#### Publish\n\nCommand   | Flags | Configuration | `NODE_ENV`*\n----------|-------|---------------|-\n`publish` | n/a   | [publish.js](config/publish.js)  | `production` or `development`\n\nUses [gh-pages](https://github.com/tschaub/gh-pages) to stand up the static output in the **./dist** directory to the [GitHub Pages](https://pages.github.com/) branch of your project's remote repository. The default `publish` configuration *requires* the `NODE_ENV=production` environment variable to push to the package repository URL defined in the **package.json** file.\n\nA custom `publish` configuration could be used to push to different remote GitHub Pages repositories.\n\nBack to [commands ^](#commands) | [table of contents ^](#contents)\n\n---\n\n### Flags\n\nFlag\u0026nbsp; | Non\u0026nbsp;abbreviated\u0026nbsp;Flag | Description\n-----------|--------------------------------|-\n`-w`       | `--watch`                      | Use Chokidar to watch for changes on concerned source files and run their scripts when changes are detected.\n`-nd`      | `--nondescript`                | Silence detailed logging (such as file writing writing) for commands. All other logs (such as script start and success) will display. **This can be used on all commands**.\n`-s`       | `--silent`                     | Disable all logging output. Note, some output will always log such as linting and errors. **This can be used on all commands**.\n`-nl`      | `--no-lint`                    | Disable ESLint and stylelint. This only works the `rollup` and `sass` command respectively. Running `npx pttrn lint -nl` will not effect.\n`-np`      | `--no-pa11y`                   | Disable Pa11y linting. This only works for the `slm` command. Running `npx pttrn pa11y -np` command will not effect.\n\n[Back to table of contents ^](#contents)\n\n### Alerts\n\n[Node Emoji](https://github.com/omnidan/node-emoji#readme) and [Chalk](https://github.com/chalk/chalk) are used to illustrate the logging alert output. The emoji symbols and colors can be modified or removed with a custom [./config/alerts.js](config/alerts.js) configuration file.\n\n\u003c!-- ### ES Configuration\n\nYou may have noticed the `scaffold` command will create a `.config/rollup.mjs` configuration file. [Node.js has stable support of the ECMAScript module spec](https://nodejs.org/api/esm.html) and they can be imported into CommonJS (Node modules). The configuration script will resolve ES modules with the **.mjs** extension over **.js** files, however, use of ES module configuration hasn't been fully tested with all of the commands. --\u003e\n\n[Back to table of contents ^](#contents)\n\n### Custom Commands\n\nAs the commands above will look for a custom configuration file for each command in the **./config** directory of your project the CLI will also resolve custom command scripts in the **./bin** directory of your project. A [sample script](bin/_sample.js) is included in this repo and can be used to start the creation of a custom command. The bare minimum a command script should include is a `run()` method.\n\n```javascript\nconst cnsl = require('@nycopportunity/pttrn/bin/util/console');\nconst alerts = require('@nycopportunity/pttrn/config/alerts');\n\nmodule.exports = {\n  run: () =\u003e {\n    cnsl.describe(`${alerts.success} My custom command`);\n  }\n};\n```\n\nFor example, a custom script named **bin/custom.js** that exports the `run()` method above can be executed with the CLI by running\n\n```shell\n$ npx pttrn custom\n✨ My custom command\n```\n\n#### Plugins\n\nCustom commands can use [other packages](https://www.npmjs.com/) that are not integrated in this project and reuse the CLI [scripts](bin/), [utilities](bin/util/), or [default configuration](config/) in different ways. Custom commands can also be packaged, published, and shared between projects as plugins. A few published [custom command plugins](#custom-command-plugins) are described below.\n\n[Back to table of contents ^](#contents)\n\n### NPM Scripts\n\nThe recommended [npm scripts](https://docs.npmjs.com/misc/scripts) below create shortcuts for using the CLI and hook into other npm methods to make starting, versioning, and publishing more convenient. They can be modified to suit the needs of a particular project. Add them to your project's *package.json* file.\n\n```json\n\"scripts\": {\n  \"start\": \"cross-env NODE_ENV=development concurrently \\\"pttrn -w\\\" \\\"pttrn serve -w\\\" -p \\\"none\\\"\",\n  \"version\": \"npm run default \u0026\u0026 git add .\",\n  \"prepublishOnly\": \"git push \u0026\u0026 git push --tags\",\n  \"publish\": \"cross-env NODE_ENV=production pttrn publish\",\n  \"default\": \"cross-env NODE_ENV=production pttrn\"\n}\n```\n\nThen each script can be run using the following outline:\n\n```shell\n$ npm run {{ script }} {{ arg }}\n```\n\nExcept for `start`, `version`, and `publish` which hook into default npm commands.\n\n```shell\n$ npm {{ start / version / publish }} {{ arg }}\n```\n\nScript           | Description\n-----------------|-\n`start`          | Hooks into the [npm-start](https://docs.npmjs.com/cli/v6/commands/npm-start) script to concurrently run the `default` and `serve` commands in watching mode for development.\n`version`        | Hooks into the [npm-version](https://docs.npmjs.com/cli/v6/commands/npm-version) script to commit a production-ready distribution and semantic version tag for publishing. It accepts an argument describing the version number to increment such as `patch`, `minor`, `major`, or `prerelease`.\n`prepublishOnly` | Hooks into the [npm `prepublishOnly` script](https://docs.npmjs.com/misc/scripts) to push the latest distribution and semantic version tag to the remote repository for publishing.\n`publish`        | Hooks into the [npm-publish](https://docs.npmjs.com/cli/v6/commands/npm-publish) script to push the contents of the **./dist** folder in the remote repositories GitHub Pages branch.\n`default`        | Runs the `default` command in production mode to build a production-ready distribution.\n\nBelow is an explainer of each script's contents.\n\nBack to [NPM scripts](#npm-scripts) | [table of contents ^](#contents)\n\n#### Start\n\n* `cross-env` - A package for the support of setting environment variables across terminal platforms.\n* `NODE_ENV=development` - Sets the node environment variable to `development`.\n* `PORT=7000` - Sets the development server port environment variable to `7000`.\n* `concurrently` - A node.js package for running multiple commands in the same session.\n* `pttrn -w` - Runs the default pttrn command in watch mode.\n* `pttrn serve -w` - Runs the serve pttrn command for starting the development server.\n* `-p \"none\"` - This is a flag for Concurrently that removes the process prefix (`[0]`) from the log.\n\nBack to [NPM scripts](#npm-scripts) | [table of contents ^](#contents)\n\n#### Version\n\n- `pttrn` - This is the same as `npx pttrn default`. It will run the CLI executable in the local **./node_modules** directory.\n- `git add .` - This stages the working directory for a commit. Since it runs after the `default` command anything compiled will be committed to the release.\n\nBack to [NPM scripts](#npm-scripts) | [table of contents ^](#contents)\n\n#### prepublishOnly\n\n- `git push` - This will push the committed release files to the origin repository.\n- `git push --tags` - This will push the committed release tag to the origin repository.\n\nBack to [NPM scripts](#npm-scripts) | [table of contents ^](#contents)\n\n#### Publish\n\n- `cross-env NODE_ENV=production` - This sets the `NODE_ENV` variable to `production` for the next command.\n- `pttrn publish` - Takes the contents of the **./dist** directory and commits it to the `gh-pages` branch to create a [GitHub Pages](https://pages.github.com) site using the [gh-pages](https://github.com/tschaub/gh-pages) package.\n\nBack to [NPM scripts](#npm-scripts) | [table of contents ^](#contents)\n\n## Adding Tailwindcss\n\nFrom [Tailwindcss](https://tailwindcss.com);\n\n\u003e ### Rapidly build modern websites without ever leaving your HTML.\n\u003e A utility-first CSS framework packed with classes like flex, pt-4, text-center, and rotate-90 that can be composed to build any design, directly in your markup.\n\nCSS utilities make it easier for developers who do not actively maintain your pattern library to create designs with components that aren't available in your stylesheet. They can also be used to modify existing components for different contexts. Tailwindcss ships as a dependency with the CLI but it needs to be configured and included in your project.\n\n### Step 1: Create your configuration file\n\nThe `scaffold` command creates a [./config/tailwindcss.js](config/tailwindcss.js). If not using the `scaffold` command, create your configuration file:\n\n```shell\ntouch config/taiwindcss.js\n```\n\nIn the configuration file, you can import your **./config/tokens.js** configuration and include design tokens from your project in the Tailwindcss configuration. You may also use the default configuration if desired.\n\n```javascript\n/**\n * Dependencies\n */\n\nconst tokens = require('tokens');\nconst tailwindcss = require('tailwindcss/defaultConfig');\n\n/**\n * Config\n */\n\nmodule.exports = {\n...\n```\n\n#### Further reference\n\n* [Tailwindcss step reference](https://tailwindcss.com/docs/installation#create-your-configuration-file)\n* [Tailwindcss configuration documentation](https://tailwindcss.com/docs/configuration)\n\n### Step 2: Include Tailwindcss in your CSS\n\nAll that's needed to include Tailwindcss in your stylesheet is to add the `@` directives somewhere in your stylesheet.\n\n```scss\n@tailwind components;\n@tailwind utilities;\n```\n\nYou may notice this does not include the `@tailwind base` tag which adds some base styling for Tailwindcss utilities. They aren't required and they can interfere with the styling of other patterns in your stylesheet. Use them at your discretion.\n\nThese directives can be added anywhere but it is recommended to keep them in the **./src/utilites** directory. The `scaffold` command creates a module directory for these directives automatically: **./src/utilities/tailwindcss**. If not using the `scaffold` command the directory and stylesheet can be added with the following `make` command:\n\n```shell\nnpx pttrn make utility tailwindcss style\n```\n\nBelow are sample contents of the stylesheet from the `scaffold` command. Copy and paste them into the stylesheet if using the `make` command above.\n\n```scss\n/**\n * Tailwindcss\n */\n\n// This injects all of Tailwind's utility classes, generated based on your\n// config file. View docs for usage; https://tailwindcss.com/docs/\n\n// @tailwind base; // Uncomment this to use Tailwindcss base styles. These may interfere with existing styles.\n@tailwind components;\n@tailwind utilities;\n```\n\nNow, in the stylesheet entry point, include the **_tailwindcss.scss** stylesheet.\n\n```scss\n@forward 'utilities/tailwindcss/tailwindcss';\n```\n\nPostCSS will inject Tailwindcss styles into your stylesheet.\n\n#### Further reference\n\n* [Tailwindcss step reference](https://tailwindcss.com/docs/installation#include-tailwind-in-your-css)\n\n### Step 3: Optional. Configure PostCSS\n\nThe CLI already configures PostCSS to inject Tailwindcss styles where the directives are included in the stylesheet. You may, however, want to further configure PostCSS, you can create a custom **./config/postcss.js** file to modify the PostCSS plugins used in your project.\n\nAdditionally, you may want to create a Tailwindcss only distribution for inclusion in other projects. This can be done by adding new distribution modules to the **./config/sass.js** configuration. The example below creates a CDN and browser friendly CSS file and a project friendly Sass file:\n\n```javascript\nmodule.exports = [\n  {\n    file: `${process.env.PWD}/src/scss/default.scss`,\n    outDir: `${process.env.PWD}/dist/styles/`,\n    outFile: 'default.css',\n    sourceMapEmbed: sass.sourceMapEmbed,\n    includePaths: sass.includePaths,\n    devModule: true // This needs to be set if we want the module to be compiled during development\n  },\n  {\n    file: `${process.env.PWD}/src/utilities/tailwindcss/_tailwindcss.scss`,\n    outDir: `${process.env.PWD}/dist/styles/`,\n    outFile: 'tailwindcss.css', // CDN and browser friendly CSS file\n    sourceMapEmbed: sass.sourceMapEmbed,\n    includePaths: sass.includePaths,\n  },\n  {\n    file: `${process.env.PWD}/src/utilities/tailwindcss/_tailwindcss.scss`,\n    outDir: `${process.env.PWD}/dist/styles/`,\n    outFile: '_tailwindcss.scss', // Project friendly Sass file\n    sourceMapEmbed: sass.sourceMapEmbed,\n    includePaths: sass.includePaths,\n  }\n];\n```\n\n### Step 4: Optional (but recommended). Purge CSS\n\nPurge CSS will read static files and remove CSS from a stylesheet that isn't being used by those files. This is recommended for projects where the pattern library will be integrated. However, for a Pattern Library, you will want to have all of the utilities present in the stylesheet. See the [optimizing for production Tailwindcss guide](https://tailwindcss.com/docs/optimizing-for-production).\n\n[Back to table of contents ^](#contents)\n\n## Creating a new `make` command template\n\nCustom templates can be created by the make script by creating a custom `make` configuration, modifying the settings, and adding a new template file in the [./config/make/](config/make/) directory. These are the steps that would need to be taken to include a [React](https://reactjs.org/) component template in the list of files created by the `make` command.\n\n### Step 1: Template contents\n\nFirst, a new base template would be defined in the **./config/make/react.jsx**;\n\n```jsx\nclass {{ Pattern }} extends React.Component {\n  render() {\n    return (\n      \u003cdiv\u003e\n        Hello {this.props.name}!\n      \u003c/div\u003e\n    );\n  }\n}\n\nReactDOM.render(\n  \u003c{{ Pattern }} name=\"World\" /\u003e,\n  document.getElementById('js-{{ pattern }}')\n);\n```\n\n#### Template Variables\n\nWithin the template string, there are a handful of variables referencing the pattern that will be replaced when the template is compiled. They are denoted by double brackets `{{  }}`;\n\n* `{{ type }}` - The pattern type defined by the command, will either be `elements`, `objects`, `utilities`.\n* `{{ prefix }}` - The pattern prefix, will either be `o-` for objects or `c-` for components.\n* `{{ pattern }}` - The lower case name of the pattern.\n* `{{ Pattern }}` - The uppercase name of the pattern.\n\n### Step 2: Filename\n\nNext, provide a filename in the `files` export attribute. Filenames use the same template variables above.\n\n```javascript\nfiles: {\n  'react': '{{ pattern }}.jsx'\n}\n```\n\n### Step 3: Is it optional?\n\nNext, if it is an optional template then add `react` to the `optional` export attribute. This will generate a prompt to create the file with a yes/no question when running the make script.\n\n```javascript\noptional: [\n  'react'\n]\n```\n\n### Step 4: Where to write the template\n\nNext, if the template should be written to every new pattern's dedicated module directory (ex; **src/{{ type }}/{{ pattern }}/**) then add `react` to the `patterns` export attribute. This is the default for most templates except views and Sass config.\n\n```javascript\npatterns: [\n  'react'\n]\n```\n\nIf you do not add `react` to the `patterns` export attribute, then you must provide a path you would like it written to in the `paths` export attribute. Below would write the new `react` template to the **./src/js/** directory.\n\n```javascript\npaths: {\n  'react': path.join(global.src, 'js', 'react')\n}\n```\n\n[Back to table of contents ^](#contents)\n\n## Optional Dependencies\n\nThe CLI ships with several optional dependencies.\n\n* Rollup Plugin Node Resolve\n* Rollup Plugin Replace\n* Chalk\n* Cross ENV\n* cssnano\n* ESLint Config Google\n* Node Emoji\n* Stylelint Config Standard\n* Tailwindcss\n\nTo omit these packages to keep your project lean, use the `--no-optional` flag when installing.\n\n```shell\nnpm install @nycopportunity/pttrn --no-optional\n```\n\nThese dependencies are required by the default configuration or recommended npm scripts. If your project is relying on many of the Framework's default configurations or you want to model your project to closely resemble the original configuration then it is recommended to include them in your project.\n\n[Back to table of contents ^](#contents)\n\n## Supporting Packages\n\nOther packages to help support pattern library development.\n\nPackage                                                               | Description\n----------------------------------------------------------------------|-\n[Patterns Scripts](https://github.com/CityOfNewYork/patterns-scripts) | A set of common utility ES modules to help keep scripting DRY and support accessibility.\n[Patterns Demo](https://github.com/CityOfNewYork/patterns-demo)       | Source code for the starter project created in the [\"start from scratch\" guide](#start-from-scratch).\n[Patterns Docs](https://github.com/CityOfNewYork/patterns-docs)       | Reusable documentation for pattern libraries created with the CLI.\n[Patterns Test](https://github.com/CityOfNewYork/patterns-test)       | Testing repository for the CLI.\n\n### Plugins\n\nRefer to [custom commands](#custom-commands) on how to create plugins.\n\nPlugin                                                                                     | Description\n-------------------------------------------------------------------------------------------|-\n[Patterns Plugin Feather](https://github.com/CityOfNewYork/patterns-plugin-feather)        | Compile a [Feather icon](https://feathericons.com/) sprite from the Feather package into the dist directory.\n[Patterns Plugin Twig](https://github.com/CityOfNewYork/patterns-plugin-twig)              | Will compile Twig view templates effectively replacing the default Slm compiler with [Twig.js](https://github.com/twigjs/twig.js/).\n[Patterns Plugin Properties](https://github.com/NYCOpportunity/patterns-plugin-properties) | Will compile JSON tokens into CSS Custom Properties using [css-vars-from-json](https://github.com/TimoBechtel/css-vars-from-json).\n\n[Back to table of contents ^](#contents)\n\n---\n\n![The Mayor's Office for Economic Opportunity](NYCMOEO_SecondaryBlue256px.png)\n\n[The Mayor's Office for Economic Opportunity](http://nyc.gov/opportunity) (NYC Opportunity) is committed to sharing open-source software that we use in our products. Feel free to ask questions and share feedback. **Interested in contributing?** See our open positions on [buildwithnyc.github.io](http://buildwithnyc.github.io/). Follow our team on [Github](https://github.com/orgs/CityOfNewYork/teams/nycopportunity) (if you are part of the [@cityofnewyork](https://github.com/CityOfNewYork/) organization) or [browse our work on Github](https://github.com/search?q=nycopportunity).","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fcityofnewyork%2Fpatterns-cli","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fcityofnewyork%2Fpatterns-cli","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fcityofnewyork%2Fpatterns-cli/lists"}