Labels
Notes
HTML
CSS
Variations

Docs

Click Events

By default, in every .f-item-preview section, all click events are blocked on buttons and on elements with an href attribute. This allows for clicking and exploring within the guide content without worrying about accidentally refreshing the page, reloading content, submitting forms, etc.

To override this behavior, add the class .allow to the element and it will be ignored by the preventLinkAndButtonEvents() function (near the end of fabricator.js)

Code Highlighting

Code highlighting is achieved with Prism.

Wrap the code you want to highlight in a <pre> block to get mono-spacing and a subtle background color. Specify the code language with a class on the <pre> block. Example: <pre class="language-markup"> for HTML or <pre class="language-css"> for CSS.

See the languages list for supported languages and class names.

Extensible Style Guide

Front-Matter Data

Any 'front-matter' data added to a material can be automatically added to the style guide output. (see Materials for instructions on adding 'front-matter' data to materials)

To create additional content types and corresponding toggles, the following files will need to be updated:

fabricator.js

src/assets/fabricator/scripts/fabricator.js

LINE ~14
  fabricator.options = {
    toggles: {
      labels: true,
      notes: true,
      code: false,
      css: false,
      NEW_TOGGLE_NAME: {true/false determines if it is checked by default}, //note the trailing comma
    },

LINE ~87
  fabricator.allItemsToggles = () => {
    const itemCache = {
      labels: document.querySelectorAll('[data-f-toggle="labels"]'),
      notes: document.querySelectorAll('[data-f-toggle="notes"]'),
      code: document.querySelectorAll('[data-f-toggle="code"]'),
      css: document.querySelectorAll('[data-f-toggle="css"]'),
      NEW_TOGGLE_NAME: document.querySelectorAll('[data-f-toggle="NEW_TOGGLE_NAME"]'), //note the trailing comma
    };

f-icons.html

src/views/layouts/includes/f-icons.html

  <symbol id="f-icon-NEW_TOGGLE_NAME" viewBox="0 0 512 512">
    <path d="SOME SVG PATH"/>
  </symbol>

This icon will be used both in the main navigation and as the toggle for each individual section. You can save any path from Illustrator as an SVG to use here. Start with a 512pt x 512pt file and 'export' it with the following settings:

//Export
'Format': SVG
[X]'Use artboards'

//SVG Options
'Styling': Inline Style
'Font': Convert To Outlines
'Images': Preserve //don't use images
'Object IDs':_ Layer Names //this doesn't matter
'Decimal': 2 //this doesn't matter
[X]'Minify' [X]'Responsive'

Open the SVG in your code editor. The output will include a <svg> tag, a <title> tag, and (probably) one <path> tag per shape. Copy all of the <path> tags and paste them into the corresponding symbol declaration (replace the <path d="SOME SVG PATH"/> in the sample markup above). At the end of each path tag, Illustrator adds a style property with a fill color. Remove that style property to allow the SVG to recolor according to the Fabricator styles.

f-controls.html

src/views/layouts/includes/f-controls.html

This adds the toggle to the main navigation.

  <div class="f-control f-global-control" data-f-toggle-control="NEW_TOGGLE_NAME" title="Toggle NEW_TOGGLE_NAME">
    <svg>
      <use xlink:href="#f-icon-NEW_TOGGLE_NAME" />
    </svg>
  </div>

f-item-controls.html

src/views/layouts/includes/f-item-controls.html

This adds the toggle to the individual component controls.

  {{#if data.NEW_TOGGLE_NAME}}
  <span class="f-control f-icon" data-f-toggle-control="NEW_TOGGLE_NAME" title="Toggle NEW_TOGGLE_NAME">
    <svg>
      <use xlink:href="#f-icon-NEW_TOGGLE_NAME" />
    </svg>
  </span>
  {{/if}}

f-item-content.html

src/views/layouts/includes/f-item-content.html

Add this content wherever you want the content to appear in the component template.

  {{#if data.NEW_TOGGLE_NAME}}
  <div class="f-item-NEW_TOGGLE_NAME" data-f-toggle="NEW_TOGGLE_NAME">
    <pre><code class="language-NEW_TOGGLE_NAME">{{{data.NEW_TOGGLE_NAME}}}</code></pre>
  </div>
  {{/if}}

OPTIONAL: index.js

node_modules/fabricator-assemble/index.js

If for some reason your data isn't rendering or you need a discrete entity that isn't bundled under data, you can update the node_module for the assembler. When using this method, omit the data. from the blocks in the content and controls files above.

LINE ~332
  // capture meta data for the material
  if (!isSubCollection) {
    assembly.materials[collection].items[key] = {
      name: toTitleCase(id),
      notes: (fileMatter.data.notes) ? md.render(fileMatter.data.notes) : '',

      NEW_TOGGLE_NAME: (fileMatter.data.NEW_TOGGLE_NAME) ? md.render(fileMatter.data.NEW_TOGGLE_NAME) : '',

      data: localData
    };
  } else {
    assembly.materials[parent].items[collection].items[key] = {
      name: toTitleCase(id.split('.')[1]),
      notes: (fileMatter.data.notes) ? md.render(fileMatter.data.notes) : '',

      NEW_TOGGLE_NAME: (fileMatter.data.NEW_TOGGLE_NAME) ? md.render(fileMatter.data.NEW_TOGGLE_NAME) : '',

      data: localData
    };
  }

Handlebars Helpers

index.js

node_modules/fabricator-assemble/index.js

Add a {{#NEW_HELPER}} function.

LINE ~219
  /* HANDLEBARS HELPER */
  Handlebars.registerHelper('NEW_HELPER', function(n, block) {
    // do something to 'block'
  });
Usage
  {{#NEW_HELPER}}
    //html or handlebars block
  {{/NEW_HELPER}}

This will apply the helper to the inner block.

Guide Vs Output

There are 2 style files and 2 script files generated by the fabricator engine:

  1. The styles and scripts that are specific to rendering the style guide are called f.css and f.js.
    • Guide-specific styles are useful for modifying the layout or behaviors within the guide without having those modifications carry over to the final toolkit files.
    • The source files for these scripts are located in the styles and scripts folders within /src/assets/fabricator/.
  2. The styles and scripts meant for usage on Bluetooth products and production code are called toolkit.css and toolkit.js.
    • Styles and scripts meant for production will also be rendered and run within the style guide. You may need to take steps to unbind() your JavaScript functions within the guide-specific files (mentioned above) if production code is interfering with the guide.
    • The source files for "toolkit" styles and scripts are located in the styles and scripts folders within /src/assets/toolkit/.
    • The toolkit.scss file also imports bootstrap styles, which are located at /node_modules/bootstrap/scss/.

Materials

See the Fabricator 'Materials' documentation for basic guidelines.

Materials have been extended in the following way:

  1. By adding "front-matter" data, you can also add code-highlighted CSS to any material. Be aware, there should already be a JavaScript utility running that collects the relevant rules and properties for each material and adds that code to the styles section for each component.

    "Front-matter" css data is written in the f-item-content.html template with {{data.css}}. It is rendered as highlighted code in the Styles section of the material. The css block needs some content in order to render, but this content will automatically be replaced by the generated content. The current standard is to add the comment <!-- display CSS -->.

---
notes: This is a note in `markdown`.
css: <!-- display CSS -->
base: .alert
variations:
  - .alert-primary
  - .alert-secondary
---
  1. Component Variations can be generated by adding variations front-matter.

    Each Variation needs to be set up as above with variations: appearing on one line, followed by - . and your variation class name. If there is a base class that is needed to create the variation (as is the case with buttons and alerts), list that class above the variations block. The guide supports multiple base classes, so if you need more than one, separate the classes with commas. If there is no base class data, (none) will be generated in the class list (as is the case with paragraphs).

  2. Generating reset buttons on components

    If a component includes a <script> block, the component will automatically have a reset button generated. Components without <script> blocks (even ones that are scripted in the toolkit script) won't receive a reset button by default.

    Ideally, all scripts that can be incorporated into the toolkit.js file should be included there instead (see Guide vs Output).

    To force a reset button to appear, simply add an empty script block (<script></script>) to the end of the the component file. If you're forcing the appearance of a reset button in this way, it's recommended that you wrap the script block in a sample block so that that the script block will be omitted from the component's HTML documentation.

Structures

Structures are groups of components. You can template structures using http://handlebarsjs.com, which will keep your markup in structures up-to-date with the components they're built on.

Use {{something}} with a component name in the middle to incorporate components from the materials folder.

Uxsg Troubleshooting

In order to create the desired behaviors and output in this style guide, some library files had to be modified. This presents a potential maintenance issue in which the modifications could be wiped out or overwritten by updating the libraries or frameworks this style guide is built upon.

Please use the template when updating this document.

This document should list all library files that have been modified. Each entry should include the:

  1. reason for modifying a library file
  2. absolute file path
  3. approximate line number(s) that have been modified
  4. modified code, with comments
  5. reason for modifying the library files, including:
    • a summary of the default behavior
    • an explanation of the problem
    • an explanation of the solution

Set Custom Bootstrap Overrides

/node_modules/bootstrap/scss/bootstrap.scss

LINE ~8-12
  // Core variables and mixins
  @import "custom"; //moved this line to the top of the list of imports
  @import "variables";
  @import "mixins";
Default Behavior

Variables in the Bootstrap 4 variables.scss file are all defined with the !default property, meaning that the variables won't be re-assigned if they already have a value.

Problem

Example Code

// _variables.scss
$white: #fff !default;
$input-bg: $white !default;

// _custom-variables.scss
$white: #f0f0f0;

// _forms.scss
.form-control {
  background-color: $input-bg;
}

In this example I want to change the value of $white from #fff to #f0f0f0.

I can override it inside _custom-variables.scss; however, the output of .form-control is still:

.form-control {
  background-color: #fff;
}

The problem is that since $white is being referenced in $input-bg before it is overwritten in _custom-variables.scss, the $input-bg variable is defined using the initial value of $white.

This behavior is true for every reference to $white throughout the style sheet. It is possible to redefine every component that references the custom variables, but that solution requires ongoing maintenance to ensure that all instances of $white correctly update to #f0f0f0 as Bootstrap is updated. This problem also grows significantly as the number of customizations increases.

Solution

By importing the _custom.scss partial before the _variables.scss partial, we're able to set our custom properties as defaults without worrying about the _variables.scss values overwriting them. This also means that all of our custom values will automatically cascade throughout the rest of the style sheets.