Skip to content
Julia Elman edited this page Nov 10, 2016 · 5 revisions

⚠️ 📓 This is a draft proposal! 📓 ⚠️

Goals:

  1. Make components more modular.
  • In Sass/SCSS environments, via @import
  • In JavaScript "bundles", via require()
  1. 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.

Layout

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.

/package.json

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:

  1. Set "main": "src/uswds.js" to enable require('uswds'), rather than require('uswds/src/uswds').
  2. Define a "postinstall" script that copies any relevant npm-installed dependency files (such the Bourbon and Neat SCSS sources) to src/vendor.

/src/

The top-level src directory contains all of the "raw" source files: SCSS, JavaScript, images, and font assets.

/src/uswds.js

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

/src/uswds.scss

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.

/src/components/

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 to usa, as in:

    // initialize all of the USWDS components with the `fda` prefix
    require('uswds/components')('fda');

/src/components/{component}/

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.

Component downloads

Components will be made downloadable via Fractal with a link to an automatically generated zip archive containing all of the relevant files. Note that:

  1. We will not include SCSS sources in the downloads, since these will reference other files external to the component directory.
  2. 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