Component reorg
⚠️ 📓 This is a draft proposal! 📓⚠️
- Make components more modular.
- Establish a self-documenting directory layout.
The layout should "make sense" in the context of GitHub, package managers such as npm, static site generators (Jekyll, Fractal, etc.), and as a static download (zip). If we're successful, this could also increase open source contributions.
Here, uswds/
is the top-level project directory in git and on
github.
uswds/ ├── fractal/ | ├── index.js | └── README.md ├── src/ | ├── components/ | | ├── some-component/ | | ├── index.js | | └── README.md | ├── abstract/ | | ├── _variables.scss | | ├── _functions.scss | | ├── _mixins.scss | | └── README.md | ├── assets/ | | ├── fonts/ | | ├── images/ | | └── README.md | ├── vendor/ | ├── uswds.js | ├── uswds.scss | └── README.md ├── package.json ├── CONTRIBUTING.md ├── LICENSE.md └── README.md
In general:
-
Every directory should contain a
README.md
that explains what is in here and how to use it. Some of these may be used to generate documentation in Fractal. -
Every individually downloadable component will need to contain a copy of our
LICENSE.md
.
The top-level package.json
file tells npm which other JavaScript modules
this project depends on and where to publish the package to when we mint new
releases. It can also be used to define common tasks. At the
very least, it will need to:
- Set
"main": "src/uswds.js"
to enablerequire('uswds')
, rather thanrequire('uswds/src/uswds')
. - Define a
"postinstall"
script that copies any relevant npm-installed dependency files (such the Bourbon and Neat SCSS sources) tosrc/vendor
.
The top-level src
directory contains all of the "raw" source files: SCSS,
JavaScript, images, and font assets.
This is the main "entry point" for the USWDS JavaScript, suitable for use with
browser bundling tools such as browserify and webpack. This is used to
generate /dist/uswds.js
, and should be referenced from the main
key in
package.json
so that it can be imported
via:
var uswds = require('uswds');
This is the main "entry point" for the monolithic USWDS stylesheet, suitable
for use with the Sass @import
statement:
@import 'uswds/uswds';
We may also choose to support Eyeglass, which would require a separate
eyeglass-exports.js
to declare where the SCSS and related assets live.
The components directory contains a separate subdirectory for each component, as well as the following files:
-
_all.scss
is an SCSS partial that will import all of the contained components. -
index.js
is a JavaScript module exporting a function that initializes all of the components with an optional HTML class and/or custom element prefix, which defaults tousa
, as in:// initialize all of the USWDS components with the `fda` prefix require('uswds/components')('fda');
Each component constists of a separate directory with one or more of the
following files, where {component}
is the name of the component:
-
README.md
is the both component's github documentation and the contents of the component's Fractal "info" tab. -
_{component}.scss
(optional) is the component's partial SCSS definition, which may only import local dependencies, and can be imported with:@import 'uswds/components/{component}/{component}';
-
{component}.main.scss
(optional) is the component's "standalone" SCSS definition, which must import any required dependencies from parent directories in order to be converted to{component}.css
. -
index.js
(optional) is the component's "partial" JavaScript behavior definition, which can be imported via:const Component = require('uswds/components/{component}');
-
{component}.js
(optional) is the static browser-ready JavaScript definition of this component, not suitable for use in bundling tools. See{component}.bundle.js
below for more info on having this file generated automatically.
Components must opt in to being displayed in Fractal by including one or more of the following files:
-
{component}.config.yml
(optional) is the component's configuration. -
{component}.template.*
(optional) is the component's view template, e.g.accordion.template.njk
. -
{component}.bundle.js
(optional) is the standalone JavaScript definition, which will be bundled into{component}.js
automatically if it exists, and can be used to document any of the component's unique JS dependencies, or basic module usage.
Components will be made downloadable via Fractal with a link to an automatically generated zip archive containing all of the relevant files. Note that:
- We will not include SCSS sources in the downloads, since these will reference other files external to the component directory.
- We may need to create some sort of manifest file for components that
require external assets, such as fonts (
typography
) or images (such as UI icons).
Here's an example layout of the components hierarchy with a couple of different "types" of components:
uswds/src/components/
├── toggle/ # an interactive (JS) component w/out CSS
| ├── toggle.bundle.js # => toggle.js
| ├── toggle.config.yml # Fractal configuration
| ├── toggle.template.njk # Fractal view template
| ├── index.js # ready for use in bundling tools
| └── README.md
├── accordion/ # an interactive (JS) component with CSS
| ├── _accordion.scss # partial CSS definition
| ├── accordion.bundle.js # => accordion.js
| ├── accordion.config.yml # Fractal configuration
| ├── accordion.main.scss # => accordion.css
| ├── accordion.template.njk # Fractal view template
| ├── index.js # ready for use in bundling tools
| └── README.md
├── button/ # pure CSS definition, but with Fractal docs
| ├── _button.scss #
| ├── button.config.yml # Fractal configuration
| ├── button.main.scss # => button.css
| ├── button.template.njk # Fractal view template
| └── README.md
└── typography/ # this will not show up in Fractal
├── _typography.scss #
├── typography.main.scss # => typography.css
└── README.md