Repository: hankchizljaw/boilerform
Branch: master
Commit: 01896b49b929
Files: 81
Total size: 118.3 KB
Directory structure:
gitextract_xrdk3epu/
├── .babelrc
├── .eslintrc
├── .github/
│ ├── ISSUE_TEMPLATE.md
│ └── PULL_REQUEST_TEMPLATE.md
├── .gitignore
├── CONTRIBUTING.md
├── LICENSE.txt
├── assets/
│ ├── js/
│ │ ├── boilerform.js
│ │ └── modules/
│ │ └── validation.js
│ └── scss/
│ ├── _config.scss
│ ├── _functions.scss
│ ├── _helpers.scss
│ ├── _reset.scss
│ ├── boilerform.scss
│ ├── components/
│ │ ├── _c-button.scss
│ │ ├── _c-check-field.scss
│ │ ├── _c-input-field.scss
│ │ ├── _c-label.scss
│ │ └── _c-select-field.scss
│ ├── layouts/
│ │ └── _l-form.scss
│ └── mixins/
│ └── _namespace.scss
├── astrum-config.json
├── dist/
│ ├── css/
│ │ └── boilerform.css
│ ├── js/
│ │ └── boilerform.js
│ └── markup/
│ ├── button/
│ │ └── default/
│ │ └── markup.html
│ ├── check-field/
│ │ ├── checkbox/
│ │ │ └── markup.html
│ │ ├── error-state/
│ │ │ └── markup.html
│ │ └── radio/
│ │ └── markup.html
│ ├── input-field/
│ │ ├── email/
│ │ │ └── markup.html
│ │ ├── error-state/
│ │ │ └── markup.html
│ │ ├── number/
│ │ │ └── markup.html
│ │ ├── search/
│ │ │ └── markup.html
│ │ ├── tel/
│ │ │ └── markup.html
│ │ ├── text/
│ │ │ └── markup.html
│ │ └── text-area/
│ │ └── markup.html
│ ├── label/
│ │ └── default/
│ │ └── markup.html
│ └── select-field/
│ ├── error-state/
│ │ └── markup.html
│ └── select-menu/
│ └── markup.html
├── generator/
│ └── dist.js
├── package.json
├── pattern-library/
│ ├── LICENSE.txt
│ ├── app/
│ │ ├── css/
│ │ │ └── styles.css
│ │ └── js/
│ │ └── main.js
│ ├── assets/
│ │ └── js/
│ │ └── patterns.js
│ ├── components/
│ │ ├── button/
│ │ │ ├── default/
│ │ │ │ ├── description.md
│ │ │ │ └── markup.html
│ │ │ └── description.md
│ │ ├── check-field/
│ │ │ ├── checkbox/
│ │ │ │ ├── description.md
│ │ │ │ └── markup.html
│ │ │ ├── description.md
│ │ │ ├── error-state/
│ │ │ │ ├── description.md
│ │ │ │ └── markup.html
│ │ │ └── radio/
│ │ │ ├── description.md
│ │ │ └── markup.html
│ │ ├── input-field/
│ │ │ ├── description.md
│ │ │ ├── email/
│ │ │ │ ├── description.md
│ │ │ │ └── markup.html
│ │ │ ├── error-state/
│ │ │ │ ├── description.md
│ │ │ │ └── markup.html
│ │ │ ├── number/
│ │ │ │ ├── description.md
│ │ │ │ └── markup.html
│ │ │ ├── search/
│ │ │ │ ├── description.md
│ │ │ │ └── markup.html
│ │ │ ├── tel/
│ │ │ │ ├── description.md
│ │ │ │ └── markup.html
│ │ │ ├── text/
│ │ │ │ ├── description.md
│ │ │ │ └── markup.html
│ │ │ └── text-area/
│ │ │ ├── description.md
│ │ │ └── markup.html
│ │ ├── label/
│ │ │ ├── default/
│ │ │ │ ├── description.md
│ │ │ │ └── markup.html
│ │ │ └── description.md
│ │ └── select-field/
│ │ ├── description.md
│ │ ├── error-state/
│ │ │ ├── description.md
│ │ │ └── markup.html
│ │ └── select-menu/
│ │ ├── description.md
│ │ └── markup.html
│ ├── data.json
│ └── index.html
├── readme.md
└── webpack.config.js
================================================
FILE CONTENTS
================================================
================================================
FILE: .babelrc
================================================
{
"presets": ["env"],
"plugins": ["babel-plugin-add-module-exports"]
}
================================================
FILE: .eslintrc
================================================
{
"parser": "babel-eslint",
"env": {
"browser": true,
"commonjs": true,
"es6": true,
"node": true
},
"rules": {
"no-const-assign": "warn",
"no-this-before-super": "warn",
"no-unreachable": "warn",
"no-unused-vars": "warn",
"constructor-super": "warn",
"valid-typeof": "warn",
"quotes": [2, "single", { "allowTemplateLiterals": true }]
}
}
================================================
FILE: .github/ISSUE_TEMPLATE.md
================================================
## Expected Behavior
## Actual Behavior
## Steps to Reproduce the Problem
1.
1.
1.
## Specifications
- Version:
- Platform:
- Browser:
- Environment/Url:
================================================
FILE: .github/PULL_REQUEST_TEMPLATE.md
================================================
Fixes Issue # (Delete if not applicable)
## Proposed Changes
-
-
-
## Add a GIF that demonstrates how this Pull Request makes you feel (optional)

================================================
FILE: .gitignore
================================================
# Common
node_modules
.DS_Store
.sass-cache
*.log
*.scssc
npm-debug.*
.env
# Compiled assets
pattern-library/assets/css
# Ignore 'sandbox'. This is where you can play around with features etc
sandbox/
================================================
FILE: CONTRIBUTING.md
================================================
# Contributing
When contributing to this repository, please first discuss the change you wish to make via issue,
email, or any other method with the owners of this repository before making a change.
Please note we have a code of conduct, please follow it in all your interactions with the project.
## Pull Request Process
1. Ensure any install or build dependencies are removed before the end of the layer when doing a
build.
2. Ensure your work is thoroughly tested, to the best of your abilities
2. You may merge the Pull Request in once you have the sign-off from a maintainer
## Code of Conduct
### Our Pledge
In the interest of fostering an open and welcoming environment, we as
contributors and maintainers pledge to making participation in our project and
our community a harassment-free experience for everyone, regardless of age, body
size, disability, ethnicity, gender identity and expression, level of experience,
nationality, personal appearance, race, religion, or sexual identity and
orientation.
### Our Standards
Examples of behavior that contributes to creating a positive environment
include:
- Using welcoming and inclusive language
- Being respectful of differing viewpoints and experiences
- Gracefully accepting constructive criticism
- Focusing on what is best for the community
- Showing empathy towards other community members
Examples of unacceptable behavior by participants include:
- The use of sexualized language or imagery and unwelcome sexual attention or
advances
- Trolling, insulting/derogatory comments, and personal or political attacks
- Public or private harassment
- Publishing others' private information, such as a physical or electronic
address, without explicit permission
- Other conduct which could reasonably be considered inappropriate in a
professional setting
### Our Responsibilities
Project maintainers are responsible for clarifying the standards of acceptable
behavior and are expected to take appropriate and fair corrective action in
response to any instances of unacceptable behavior.
Project maintainers have the right and responsibility to remove, edit, or
reject comments, commits, code, wiki edits, issues, and other contributions
that are not aligned to this Code of Conduct, or to ban temporarily or
permanently any contributor for other behaviors that they deem inappropriate,
threatening, offensive, or harmful.
### Scope
This Code of Conduct applies both within project spaces and in public spaces
when an individual is representing the project or its community. Examples of
representing a project or community include using an official project e-mail
address, posting via an official social media account, or acting as an appointed
representative at an online or offline event. Representation of a project may be
further defined and clarified by project maintainers.
### Enforcement
Instances of abusive, harassing, or otherwise unacceptable behavior may be
reported by contacting the project team at andy@hankchizljaw.io. All
complaints will be reviewed and investigated and will result in a response that
is deemed necessary and appropriate to the circumstances. The project team is
obligated to maintain confidentiality with regard to the reporter of an incident.
Further details of specific enforcement policies may be posted separately.
Project maintainers who do not follow or enforce the Code of Conduct in good
faith may face temporary or permanent repercussions as determined by other
members of the project's leadership.
### Attribution
This Code of Conduct is adapted from the [Contributor Covenant][homepage], version 1.4,
available at [http://contributor-covenant.org/version/1/4][version]
[homepage]: http://contributor-covenant.org
[version]: http://contributor-covenant.org/version/1/4/
================================================
FILE: LICENSE.txt
================================================
MIT License
Copyright (c) 2018 hankchizljaw.io and other contributors
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
================================================
FILE: assets/js/boilerform.js
================================================
import Validation from './modules/validation';
// Import Sass so that webpack picks it up
require('../scss/boilerform.scss');
(function() {
// Look for child and root forms
const boilerforms = [...document.querySelectorAll('.boilerform form, form.boilerform')];
if(boilerforms.length) {
// Add a validator to each form instance
boilerforms.map(item => {
let validationInstance = new Validation(item);
validationInstance.init();
});
}
}());
================================================
FILE: assets/js/modules/validation.js
================================================
export default class Validation {
/**
* Load up an instance of Validation
* @param {HTMLFormElement} baseForm
*/
constructor(baseForm) {
this.baseForm = baseForm;
// Load child input elements
this.inputElems = [...baseForm.querySelectorAll('input, textarea, select')];
}
/**
* Public init method
*/
init() {
let self = this;
self.bind();
}
/**
* Bind events to input elements
*/
bind() {
let self = this;
// Add an invalid listener that
self.inputElems.map(item => {
item.addEventListener('invalid', () => {
self.processValidity(item);
self.checkSiblings(item);
}, false);
});
}
/**
* Toggle the visual state of an item based on the based state key
* @param {HTMLElement} item
* @param {String} state
*/
process(item, state = 'invalid') {
switch(state) {
case 'invalid':
item.classList.add('is-error');
break;
default:
item.classList.remove('is-error');
break;
}
}
/**
* Filter sibling elements and run them through the validity checker
*
* @param {HTMLFormElement} exludedField
*/
checkSiblings(exludedField) {
let self = this;
self.inputElems
.filter(item => item !== exludedField)
.map(item => self.processValidity(item));
}
/**
* Run some checks to determine if the passed item is valid or not
* @param {HTMLElement} item
*/
processValidity(item) {
let self = this;
// If an item is valid, run the processor and bail
if(item.validity.valid) {
self.process(item, 'valid');
return;
}
// If we're here, it's invalid
self.process(item, 'invalid');
}
};
================================================
FILE: assets/scss/_config.scss
================================================
// Colors
$colors: (
base: (
text: #141414,
border: #cccccc
),
button: (
background: #666666,
background--hover: #888888,
text: #ffffff
),
check: (
decor: #eeeeee,
decor--active: #aaaaaa,
decor__inner: #888888
),
field: (
background: #ffffff
),
state: (
error: #cf0b00
)
);
// Metrics
$button-padding: 11px 25px 10px 25px;
$check-field-decor-size: 20px;
$check-field-flow: 10px;
$check-field-label-padding: 3px 0 0 10px;
$input-field-vertical-padding: 10px;
$input-field-horizontal-padding: 15px;
$input-field-padding: #{ $input-field-vertical-padding + 1 } $input-field-horizontal-padding $input-field-vertical-padding $input-field-horizontal-padding;
$multiline-min-height: 80px;
// Decorative
$border-radius: 2px;
// Typography
$base-font-family: sans-serif;
$base-font-size: 16px;
$input-field-font-size: 1rem;
================================================
FILE: assets/scss/_functions.scss
================================================
/*------------------------------------*\
COLOR
Pass in a group name and a key
to get a value.
E.G color(field, background) will return
the background item in the field group.
Colors are defined in $colors in _config.scss
\*------------------------------------*/
@function color($group, $color) {
@return map-get(map-get($colors, $group), $color);
}
================================================
FILE: assets/scss/_helpers.scss
================================================
// All input fields share these styles. Also includes select menus
%c-field-shared-inputs {
background: color(field, background);
border: 1px solid color(base, border);
padding: $input-field-padding;
border-radius: $border-radius;
font-size: $input-field-font-size;
}
// Visually hide an element, but allow a screen-reader to see it
%visually-hidden {
display: block;
height: 1px;
width: 1px;
overflow: hidden;
clip: rect(1px 1px 1px 1px);
clip: rect(1px, 1px, 1px, 1px);
clip-path: inset(1px);
white-space: nowrap;
position: absolute;
}
================================================
FILE: assets/scss/_reset.scss
================================================
@include namespace(true) {
// Set base pixel size for REM units to work off
font-size: $base-font-size;
// Set the base color
color: color(base, text);
// Set base border color
border-color: color(base, border);
// Box sizing border-box FTW
&,
& * {
box-sizing: border-box;
}
// All field elements
[class*="-field"] {
margin: 0;
display: inline-block;
vertical-align: middle;
white-space: normal;
line-height: 1.1;
font-family: $base-font-family;
}
// All decorative elements
[class*="decor"] {
line-height: 0;
}
// Turn off the recent search in WebKit.
::-webkit-search-decoration {
display: none;
}
// Normalise form field line-height in WebKit
input::-webkit-input-placeholder,
textarea::-webkit-input-placeholder,
select::-webkit-input-placeholder {
line-height: normal;
}
// Make a search box appear like a text box
input[type="search"] {
-webkit-appearance: textfield;
}
}
================================================
FILE: assets/scss/boilerform.scss
================================================
// Pull config
@import "config";
// Mixins
@import "mixins/namespace";
// Functions
@import "functions";
// Helpers
@import "helpers";
// Resets
@import "reset";
// Components
@import "components/c-button";
@import "components/c-check-field";
@import "components/c-input-field";
@import "components/c-label";
@import "components/c-select-field";
// Layouts
@import "layouts/l-form";
// Shared styles
@include namespace(true) {
// Override border color for errors
.is-error {
&,
[class*="menu"],
[class*="check"] {
border-color: color(state, error);
// Remove default focus and replace with a heavy shadow if invalid
&:focus {
outline: none;
box-shadow: 0 0 0 2px color(state, error);
}
}
}
}
================================================
FILE: assets/scss/components/_c-button.scss
================================================
/*------------------------------------*\
BUTTON COMPONENT
Base button styles and reset
\*------------------------------------*/
$namespace: ".c-button";
#{ $namespace } {
@include namespace() {
display: inline-block;
border: none;
padding: 0;
margin: 0;
text-decoration: none;
background: color(button, background);
color: color(button, text);
padding: $button-padding;
font-family: $base-font-family;
font-size: 1rem;
border-radius: $border-radius;
cursor: pointer;
text-align: center;
-webkit-appearance: none;
-moz-appearance: none;
&:hover,
&:focus {
background: color(button, background--hover);
}
}
}
================================================
FILE: assets/scss/components/_c-check-field.scss
================================================
/*------------------------------------*\
CHECK FIELD COMPONENT
Radio buttons and checkboxes
\*------------------------------------*/
$namespace: ".c-check-field";
#{ $namespace } {
@include namespace() {
display: flex;
flex-direction: row;
align-items: flex-start;
// Visually hide the input
&__input {
@extend %visually-hidden;
}
&__decor {
display: block;
width: $check-field-decor-size;
height: $check-field-decor-size;
flex-shrink: 0;
background: color(check, decor);
border: 1px solid color(base, border);
border-radius: $border-radius;
position: relative;
cursor: pointer;
&:after {
content: "";
speak: none;
display: block;
opacity: 0;
width: 70%;
height: 70%;
position: absolute;
top: 15%;
left: 15%;
background: color(check, decor__inner);
border-radius: #{ $border-radius / 2 };
}
}
&__label {
padding: $check-field-label-padding;
cursor: pointer;
}
// Radio modifier
&--radio #{ $namespace }__decor {
&,
&:after {
border-radius: 50%;
}
}
// Checked state
&__input:checked ~ [class*="decor"] {
&:after {
opacity: 1;
}
}
// Focused state
&__input:focus ~ [class*="decor"] {
outline: 1px dotted #212121;
outline: 5px auto -webkit-focus-ring-color;
}
// Flow between instances
& + #{ $namespace } {
padding-top: $check-field-flow;
}
}
}
================================================
FILE: assets/scss/components/_c-input-field.scss
================================================
/*------------------------------------*\
INPUT FIELD COMPONENT
All input based form field elements
\*------------------------------------*/
$namespace: ".c-input-field";
#{ $namespace } {
@include namespace() {
@extend %c-field-shared-inputs;
// Reduce right-hand padding for number inputs
&[type="number"] {
padding-right: #{ $input-field-padding / 2 };
}
// Multiline fields like <textarea> etc
&--multiline {
vertical-align: top;
overflow: auto;
width: 100%;
&:not([rows]) {
min-height: $multiline-min-height;
}
}
}
}
================================================
FILE: assets/scss/components/_c-label.scss
================================================
/*------------------------------------*\
LABEL COMPONENT
A simple form label
\*------------------------------------*/
$namespace: ".c-label";
#{ $namespace } {
@include namespace() {
display: inline;
font-family: $base-font-family;
font-weight: 700;
font-size: 0.88rem;
// Only add a pointer cursor if there's a for attribute
&[for] {
cursor: pointer;
}
// Create a line break
&:after {
content: "\A";
white-space: pre;
}
// Add space between a label and a field
& + [class*="field"] {
margin-top: 2px;
}
}
}
================================================
FILE: assets/scss/components/_c-select-field.scss
================================================
/*------------------------------------*\
SELECT FIELD
Option driven fields such as
<select> menus
\*------------------------------------*/
$namespace: ".c-select-field";
#{ $namespace } {
@include namespace() {
display: inline-block;
position: relative;
&__menu {
@extend %c-field-shared-inputs;
-webkit-appearance: none;
-moz-appearance: none;
padding-right: #{ $input-field-horizontal-padding * 3 };
// Undo Firefox focus ring
&:-moz-focusring {
color: transparent;
text-shadow: 0 0 0 color(base, text);
}
// Remove arrow in IE
&::-ms-expand {
display: none;
}
}
&__decor {
position: absolute;
top: 50%;
right: $input-field-horizontal-padding;
pointer-events: none;
}
}
}
================================================
FILE: assets/scss/layouts/_l-form.scss
================================================
/*------------------------------------*\
FORM LAYOUT
The main form layout that gives
you rythm, alignment and flow
\*------------------------------------*/
$namespace: ".l-form";
#{ $namespace } {
@include namespace() {
}
}
================================================
FILE: assets/scss/mixins/_namespace.scss
================================================
/*------------------------------------*\
NAMESPACE
This mixin encapsulates CSS within
a namespace to prevent outside
conflicts as much as possible.
\*------------------------------------*/
@mixin namespace($isRoot: false) {
@if ($isRoot == true) {
.boilerform {
@content;
}
}
@else {
.boilerform & {
@content;
}
}
}
================================================
FILE: astrum-config.json
================================================
{
"path": "pattern-library"
}
================================================
FILE: dist/css/boilerform.css
================================================
/*------------------------------------* NAMESPACE
This mixin encapsulates CSS within
a namespace to prevent outside
conflicts as much as possible.
\*------------------------------------*/
/*------------------------------------* COLOR
Pass in a group name and a key
to get a value.
E.G color(field, background) will return
the background item in the field group.
Colors are defined in $colors in _config.scss
\*------------------------------------*/
.boilerform .c-input-field, .boilerform .c-select-field__menu {
background: #ffffff;
border: 1px solid #cccccc;
padding: 11px 15px 10px 15px;
border-radius: 2px;
font-size: 1rem; }
.boilerform .c-check-field__input {
display: block;
height: 1px;
width: 1px;
overflow: hidden;
clip: rect(1px 1px 1px 1px);
clip: rect(1px, 1px, 1px, 1px);
clip-path: inset(1px);
white-space: nowrap;
position: absolute; }
.boilerform {
font-size: 16px;
color: #141414;
border-color: #cccccc; }
.boilerform,
.boilerform * {
box-sizing: border-box; }
.boilerform [class*="-field"] {
margin: 0;
display: inline-block;
vertical-align: middle;
white-space: normal;
line-height: 1.1;
font-family: sans-serif; }
.boilerform [class*="decor"] {
line-height: 0; }
.boilerform ::-webkit-search-decoration {
display: none; }
.boilerform input::-webkit-input-placeholder,
.boilerform textarea::-webkit-input-placeholder,
.boilerform select::-webkit-input-placeholder {
line-height: normal; }
.boilerform input[type="search"] {
-webkit-appearance: textfield; }
/*------------------------------------* BUTTON COMPONENT
Base button styles and reset
\*------------------------------------*/
.boilerform .c-button {
display: inline-block;
border: none;
padding: 0;
margin: 0;
text-decoration: none;
background: #666666;
color: #ffffff;
padding: 11px 25px 10px 25px;
font-family: sans-serif;
font-size: 1rem;
border-radius: 2px;
cursor: pointer;
text-align: center;
-webkit-appearance: none;
-moz-appearance: none; }
.boilerform .c-button:hover, .boilerform .c-button:focus {
background: #888888; }
/*------------------------------------* CHECK FIELD COMPONENT
Radio buttons and checkboxes
\*------------------------------------*/
.boilerform .c-check-field {
display: flex;
flex-direction: row;
align-items: flex-start; }
.boilerform .c-check-field__decor {
display: block;
width: 20px;
height: 20px;
flex-shrink: 0;
background: #eeeeee;
border: 1px solid #cccccc;
border-radius: 2px;
position: relative;
cursor: pointer; }
.boilerform .c-check-field__decor:after {
content: "";
speak: none;
display: block;
opacity: 0;
width: 70%;
height: 70%;
position: absolute;
top: 15%;
left: 15%;
background: #888888;
border-radius: 1px; }
.boilerform .c-check-field__label {
padding: 3px 0 0 10px;
cursor: pointer; }
.boilerform .c-check-field--radio .c-check-field__decor, .boilerform .c-check-field--radio .c-check-field__decor:after {
border-radius: 50%; }
.boilerform .c-check-field__input:checked ~ [class*="decor"]:after {
opacity: 1; }
.boilerform .c-check-field__input:focus ~ [class*="decor"] {
outline: 1px dotted #212121;
outline: 5px auto -webkit-focus-ring-color; }
.boilerform .c-check-field + .c-check-field {
padding-top: 10px; }
/*------------------------------------* INPUT FIELD COMPONENT
All input based form field elements
\*------------------------------------*/
.boilerform .c-input-field[type="number"] {
padding-right: 11px 15px 10px 15px / 2; }
.boilerform .c-input-field--multiline {
vertical-align: top;
overflow: auto;
width: 100%; }
.boilerform .c-input-field--multiline:not([rows]) {
min-height: 80px; }
/*------------------------------------* LABEL COMPONENT
A simple form label
\*------------------------------------*/
.boilerform .c-label {
display: inline;
font-family: sans-serif;
font-weight: 700;
font-size: 0.88rem; }
.boilerform .c-label[for] {
cursor: pointer; }
.boilerform .c-label:after {
content: "\A";
white-space: pre; }
.boilerform .c-label + [class*="field"] {
margin-top: 2px; }
/*------------------------------------* SELECT FIELD
Option driven fields such as
<select> menus
\*------------------------------------*/
.boilerform .c-select-field {
display: inline-block;
position: relative; }
.boilerform .c-select-field__menu {
-webkit-appearance: none;
-moz-appearance: none;
padding-right: 45px; }
.boilerform .c-select-field__menu:-moz-focusring {
color: transparent;
text-shadow: 0 0 0 #141414; }
.boilerform .c-select-field__menu::-ms-expand {
display: none; }
.boilerform .c-select-field__decor {
position: absolute;
top: 50%;
right: 15px;
pointer-events: none; }
/*------------------------------------* FORM LAYOUT
The main form layout that gives
you rythm, alignment and flow
\*------------------------------------*/
.boilerform .is-error,
.boilerform .is-error [class*="menu"],
.boilerform .is-error [class*="check"] {
border-color: #cf0b00; }
.boilerform .is-error:focus,
.boilerform .is-error [class*="menu"]:focus,
.boilerform .is-error [class*="check"]:focus {
outline: none;
box-shadow: 0 0 0 2px #cf0b00; }
/*# sourceMappingURL=boilerform.css.map*/
================================================
FILE: dist/js/boilerform.js
================================================
(function webpackUniversalModuleDefinition(root, factory) {
if(typeof exports === 'object' && typeof module === 'object')
module.exports = factory();
else if(typeof define === 'function' && define.amd)
define("boilerform", [], factory);
else if(typeof exports === 'object')
exports["boilerform"] = factory();
else
root["boilerform"] = factory();
})(typeof self !== 'undefined' ? self : this, function() {
return /******/ (function(modules) { // webpackBootstrap
/******/ // The module cache
/******/ var installedModules = {};
/******/
/******/ // The require function
/******/ function __webpack_require__(moduleId) {
/******/
/******/ // Check if module is in cache
/******/ if(installedModules[moduleId]) {
/******/ return installedModules[moduleId].exports;
/******/ }
/******/ // Create a new module (and put it into the cache)
/******/ var module = installedModules[moduleId] = {
/******/ i: moduleId,
/******/ l: false,
/******/ exports: {}
/******/ };
/******/
/******/ // Execute the module function
/******/ modules[moduleId].call(module.exports, module, module.exports, __webpack_require__);
/******/
/******/ // Flag the module as loaded
/******/ module.l = true;
/******/
/******/ // Return the exports of the module
/******/ return module.exports;
/******/ }
/******/
/******/
/******/ // expose the modules object (__webpack_modules__)
/******/ __webpack_require__.m = modules;
/******/
/******/ // expose the module cache
/******/ __webpack_require__.c = installedModules;
/******/
/******/ // define getter function for harmony exports
/******/ __webpack_require__.d = function(exports, name, getter) {
/******/ if(!__webpack_require__.o(exports, name)) {
/******/ Object.defineProperty(exports, name, {
/******/ configurable: false,
/******/ enumerable: true,
/******/ get: getter
/******/ });
/******/ }
/******/ };
/******/
/******/ // getDefaultExport function for compatibility with non-harmony modules
/******/ __webpack_require__.n = function(module) {
/******/ var getter = module && module.__esModule ?
/******/ function getDefault() { return module['default']; } :
/******/ function getModuleExports() { return module; };
/******/ __webpack_require__.d(getter, 'a', getter);
/******/ return getter;
/******/ };
/******/
/******/ // Object.prototype.hasOwnProperty.call
/******/ __webpack_require__.o = function(object, property) { return Object.prototype.hasOwnProperty.call(object, property); };
/******/
/******/ // __webpack_public_path__
/******/ __webpack_require__.p = "";
/******/
/******/ // Load entry module and return exports
/******/ return __webpack_require__(__webpack_require__.s = 0);
/******/ })
/************************************************************************/
/******/ ([
/* 0 */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
var _validation = __webpack_require__(1);
var _validation2 = _interopRequireDefault(_validation);
var _boilerform = __webpack_require__(2);
var _boilerform2 = _interopRequireDefault(_boilerform);
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
function _toConsumableArray(arr) { if (Array.isArray(arr)) { for (var i = 0, arr2 = Array(arr.length); i < arr.length; i++) { arr2[i] = arr[i]; } return arr2; } else { return Array.from(arr); } }
// Import Sass so that webpack picks it up
(function () {
// Look for child and root forms
var boilerforms = [].concat(_toConsumableArray(document.querySelector('.boilerform form, form.boilerform')));
if (boilerforms.length) {
// Add a validator to each form instance
boilerforms.map(function (item) {
var validationInstance = new _validation2.default(item);
validationInstance.init();
});
}
})();
/***/ }),
/* 1 */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();
function _toConsumableArray(arr) { if (Array.isArray(arr)) { for (var i = 0, arr2 = Array(arr.length); i < arr.length; i++) { arr2[i] = arr[i]; } return arr2; } else { return Array.from(arr); } }
function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
var Validation = function () {
/**
* Load up an instance of Validation
* @param {HTMLFormElement} baseForm
*/
function Validation(baseForm) {
_classCallCheck(this, Validation);
this.baseForm = baseForm;
// Load child input elements
this.inputElems = [].concat(_toConsumableArray(baseForm.querySelectorAll('input, textarea, select')));
}
/**
* Public init method
*/
_createClass(Validation, [{
key: 'init',
value: function init() {
var self = this;
self.bind();
self.setCustomValidationMessages();
}
/**
* Bind events to input elements
*/
}, {
key: 'bind',
value: function bind() {
var self = this;
// Add an invalid listener that
self.inputElems.map(function (item) {
item.addEventListener('invalid', function (evt) {
self.processValidity(item);
}, false);
});
}
/**
* Run through each item and check they have a `data-validation-message` attribute.
* If so, set a custom validation message with that value
*/
}, {
key: 'setCustomValidationMessages',
value: function setCustomValidationMessages() {
var self = this;
self.inputElems.map(function (item) {
self.setCustomValidationMessage(item);
});
}
/**
* Set a custom validation message if item needs it
* @param {HTMLElement} item
*/
}, {
key: 'setCustomValidationMessage',
value: function setCustomValidationMessage(item) {
var self = this;
if (item.hasAttribute('data-validation-message')) {
item.setCustomValidity(item.getAttribute('data-validation-message'));
}
}
/**
* Toggle the visual state of an item based on the based state key
* @param {HTMLElement} item
* @param {String} state
*/
}, {
key: 'process',
value: function process(item) {
var state = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 'invalid';
var self = this;
switch (state) {
case 'invalid':
item.classList.add('is-error');
self.setCustomValidationMessage(item);
break;
default:
item.classList.remove('is-error');
break;
}
}
/**
* Run some checks to determine if the passed item is valid or not
* @param {HTMLElement} item
*/
}, {
key: 'processValidity',
value: function processValidity(item) {
var self = this;
// If an item is valid, run the processor and bail
if (item.validity.valid) {
self.process(item, 'valid');
self.checkSiblings(item);
return;
}
// Before we determine it as invalid, check to see if there's a custom error
if (item.validity.customError) {
// Now let's check against some states
if (!item.validity.badInput && !item.validity.patternMismatch && !item.validity.rangeOverflow && !item.validity.rangeUnderflow && !item.validity.stepMismatch && !item.validity.tooLong && !item.validity.tooShort && !item.validity.typeMismatch && !item.validity.valueMissing) {
// It's valid, so process accordingly
item.setCustomValidity('');
self.process(item, 'valid');
self.checkSiblings(item);
return;
}
}
// If we're here, it's invalid
self.process(item, 'invalid');
self.checkSiblings(item);
}
/**
* Check an item's siblings validty state
* @param {HTMLElement} item
*/
}, {
key: 'checkSiblings',
value: function checkSiblings(item) {
var self = this;
// Find siblings that aren't this item and that are required
var inputElems = self.inputElems.filter(function (elem) {
return elem != item && elem.hasAttribute('required');
});
if (inputElems.length) {
// Run each item through the processor
inputElems.map(function (item) {
self.processValidity(item);
});
}
}
}]);
return Validation;
}();
exports.default = Validation;
;
module.exports = exports['default'];
/***/ }),
/* 2 */
/***/ (function(module, exports) {
// removed by extract-text-webpack-plugin
/***/ })
/******/ ]);
});
//# sourceMappingURL=boilerform.js.map
================================================
FILE: dist/markup/button/default/markup.html
================================================
<button class="c-button">A button</button>
================================================
FILE: dist/markup/check-field/checkbox/markup.html
================================================
<div class="c-check-field">
<input type="checkbox" name="checkbox-field" id="checkbox-field" class="c-check-field__input" />
<label for="checkbox-field" class="c-check-field__decor" aria-hidden="true" role="presentation"></label>
<label for="checkbox-field" class="c-check-field__label">A checkbox field</label>
</div>
================================================
FILE: dist/markup/check-field/error-state/markup.html
================================================
<div class="[ c-check-field ] [ is-error ]">
<input type="checkbox" name="checkbox-error-field" id="checkbox-error-field" class="c-check-field__input" />
<label for="checkbox-error-field" class="c-check-field__decor" aria-hidden="true" role="presentation"></label>
<label for="checkbox-error-field" class="c-check-field__label">A checkbox field</label>
</div>
<div class="[ c-check-field c-check-field--radio ] [ is-error ]">
<input type="radio" name="radio-error-field" id="radio-error-field" class="c-check-field__input" />
<label for="radio-error-field" class="c-check-field__decor" aria-hidden="true" role="presentation"></label>
<label for="radio-error-field" class="c-check-field__label">A radio button</label>
</div>
================================================
FILE: dist/markup/check-field/radio/markup.html
================================================
<div class="c-check-field c-check-field--radio">
<input type="radio" name="checkbox-field" id="checkbox-radio-field-1" class="c-check-field__input" />
<label for="checkbox-radio-field-1" class="c-check-field__decor" aria-hidden="true" role="presentation"></label>
<label for="checkbox-radio-field-1" class="c-check-field__label">A radio button</label>
</div>
<div class="c-check-field c-check-field--radio">
<input type="radio" name="checkbox-field" id="checkbox-radio-field-2" class="c-check-field__input" />
<label for="checkbox-radio-field-2" class="c-check-field__decor" aria-hidden="true" role="presentation"></label>
<label for="checkbox-radio-field-2" class="c-check-field__label">Another radio button</label>
</div>
================================================
FILE: dist/markup/input-field/email/markup.html
================================================
<input type="email" name="" id="" autocapitalize="none" autocorrect="off" class="c-input-field" value="user@email.com" />
================================================
FILE: dist/markup/input-field/error-state/markup.html
================================================
<input type="text" name="" id="" class="[ c-input-field ] [ is-error ]" value="Generic text" />
================================================
FILE: dist/markup/input-field/number/markup.html
================================================
<input type="number" name="" id="" min="1" max="999" step="1" class="c-input-field" value="123" />
================================================
FILE: dist/markup/input-field/search/markup.html
================================================
<input type="search" name="" id="" autocorrect="off" class="c-input-field" value="Some search terms" />
================================================
FILE: dist/markup/input-field/tel/markup.html
================================================
<input type="tel" name="" id="" class="c-input-field" value="01234 567 890" />
================================================
FILE: dist/markup/input-field/text/markup.html
================================================
<input type="text" name="" id="" class="c-input-field" value="Generic text" />
================================================
FILE: dist/markup/input-field/text-area/markup.html
================================================
<textarea name="" id="" class="c-input-field c-input-field--multiline">Some multiline text</textarea>
================================================
FILE: dist/markup/label/default/markup.html
================================================
<label for="" class="c-label">A label for a field</label>
<input class="c-input-field" value="fdsfds" />
================================================
FILE: dist/markup/select-field/error-state/markup.html
================================================
<div class="[ c-select-field ] [ is-error ]">
<select name="" id="" class="c-select-field__menu">
<option>Select an item</option>
<option value="1">Item 1</option>
<option value="2">Item 2</option>
<option value="3">Item 3</option>
<option value="4">Item 5</option>
</select>
<span class="c-select-field__decor" aria-hidden="true" role="presentation">▾</span>
</div>
================================================
FILE: dist/markup/select-field/select-menu/markup.html
================================================
<div class="c-select-field">
<select name="" id="" class="c-select-field__menu">
<option>Select an item</option>
<option value="1">Item 1</option>
<option value="2">Item 2</option>
<option value="3">Item 3</option>
<option value="4">Item 5</option>
</select>
<span class="c-select-field__decor" aria-hidden="true" role="presentation">▾</span>
</div>
================================================
FILE: generator/dist.js
================================================
var findRemoveSync = require('find-remove');
var fs = require('fs');
var ncp = require('ncp');
var path = require('path');
var rimraf = require('rimraf');
// Delete the markup dist dir
rimraf(path.join(__dirname, '../dist/markup'), function() {
// Copy the components from the pattern lib
ncp(path.join(__dirname, '../pattern-library/components'), path.join(__dirname, '../dist/markup'), function(error) {
if(error) return console.log(error);
// Remove all markdown files
findRemoveSync(path.join(__dirname, '../dist/markup'), { extensions: '.md' });
});
});
================================================
FILE: package.json
================================================
{
"name": "boilerform",
"version": "1.1.1",
"description": "A little collection of common form elements that have base markup and CSS set up for you.",
"scripts": {
"sass:dist-min": "uglifycss dist/css/boilerform.css > dist/css/boilerform.min.css",
"watch": "webpack --watch",
"build": "NODE_ENV=production webpack && npm run sass:dist-min && node generator/dist.js && echo Done 👍🏼"
},
"repository": {
"type": "git",
"url": "git+https://github.com/hankchizljaw/boilerform.git"
},
"author": "hankchizljaw",
"license": "MIT",
"bugs": {
"url": "https://github.com/hankchizljaw/boilerform/issues"
},
"homepage": "https://github.com/hankchizljaw/boilerform#readme",
"devDependencies": {
"babel-core": "^6.26.0",
"babel-loader": "^7.1.2",
"babel-plugin-add-module-exports": "^0.2.1",
"babel-preset-env": "^1.6.1",
"css-loader": "^0.28.7",
"dotenv": "^5.0.1",
"extract-text-webpack-plugin": "^3.0.2",
"find-remove": "^1.2.0",
"ncp": "^2.0.0",
"node-sass": "^4.7.2",
"rimraf": "^2.6.2",
"sass-loader": "^6.0.6",
"uglifycss": "0.0.27",
"webpack": "^3.10.0"
}
}
================================================
FILE: pattern-library/LICENSE.txt
================================================
Copyright (c) Astrum by No Divide Studio Ltd (http://nodividestudio.com)
Permission is hereby granted, free of charge, to any person obtaining a copy of
this software and associated documentation files (the "Software"), to deal in
the Software without restriction, including without limitation the rights to
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
of the Software, and to permit persons to whom the Software is furnished to do
so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
================================================
FILE: pattern-library/app/css/styles.css
================================================
/**
* Base styles
* ----------------------------------------//
*/
.ndpl-body {
background-color: #FFF;
-ms-overflow-style: -ms-autohiding-scrollbar;
margin: 0;
padding: 0;
}
[class^="ndpl-"], [class*=" ndpl-"] {
box-sizing: border-box;
}
.ndpl-disable-scrolling {
overflow: hidden;
}
.ndpl-body.nav-open {
overflow-y: hidden;
}
.ndpl-loading__title,
.ndpl-error,
.ndpl-info,
.ndpl-header,
.ndpl-sidebar,
.ndpl-intro,
.ndpl-library__title,
.ndpl-group__description,
.ndpl-component__title,
.ndpl-component__description,
.ndpl-component__label,
.ndpl-component__code-toggle,
.ndpl-component__color,
.ndpl-page,
.ndpl-nav__title,
.ndpl-sidebar__title {
font-family: 'Open Sans', 'Trebuchet MS', 'Lucida Grande', 'Lucida Sans Unicode', 'Lucida Sans', Tahoma, sans-serif;
}
/* Heading type sizes */
.ndpl-library__title {
font-size: 27px;
font-weight: 400;
line-height: 36px;
}
.ndpl-component__title {
font-size: 18px;
font-weight: 300;
line-height: 32px;
}
/* Body type size */
.ndpl-page,
.ndpl-intro,
.ndpl-group__description,
.ndpl-component__description {
font-size: 12px;
font-weight: 300;
line-height: 24px;
}
/* Page sizes */
.ndpl-page h1 { margin-bottom: 24px; }
.ndpl-page h2,
.ndpl-page h3,
.ndpl-page h4,
.ndpl-page h5,
.ndpl-page h6 { margin: 24px 0 12px; }
.ndpl-page h2:first-child,
.ndpl-page h3:first-child,
.ndpl-page h4:first-child,
.ndpl-page h5:first-child,
.ndpl-page h6:first-child { margin-top: 0; }
.ndpl-page h1 { font-size: 26px; font-weight: 400; line-height: 36px; }
.ndpl-page h2 { font-size: 21px; font-weight: 300; line-height: 36px; }
.ndpl-page h3 { font-size: 18px; font-weight: 300; line-height: 32px; }
.ndpl-page h4 { font-size: 16px; font-weight: 300; line-height: 27px; }
.ndpl-page h5 { font-size: 14px; font-weight: 300; line-height: 24px; }
.ndpl-page h6 { font-size: 14px; font-weight: 400; line-height: 24px; }
.ndpl-page code,
.ndpl-component__description code,
.ndpl-group__description code {
display: inline-block;
color: #BABEC7;
border: 1px solid #E1E1E1;
border-radius: 3px;
line-height: 18px;
padding: 0 3px;
}
.ndpl-page a,
.ndpl-page a[href] {
text-decoration: none;
}
.ndpl-page a:hover,
.ndpl-page a[href]:hover {
text-decoration: underline;
}
.ndpl-page p {
margin-bottom: 24px;
}
@media only screen and (min-width: 60em) {
.ndpl-page h1 { margin-bottom: 48px; }
.ndpl-page h2,
.ndpl-page h3,
.ndpl-page h4,
.ndpl-page h5,
.ndpl-page h6 { margin: 48px 0 24px; }
/* Heading type sizes */
.ndpl-library__title {
font-size: 36px;
line-height: 36px;
}
.ndpl-component__title {
font-size: 21px;
line-height: 32px;
}
/* Body type size */
.ndpl-page,
.ndpl-intro,
.ndpl-group__description,
.ndpl-component__description {
font-size: 14px;
line-height: 21px;
}
/* Page sizes */
.ndpl-page h1 { font-size: 36px; line-height: 36px; }
.ndpl-page h2 { font-size: 28px; line-height: 36px; }
.ndpl-page h3 { font-size: 21px; line-height: 32px; }
.ndpl-page h4 { font-size: 18px; line-height: 27px; }
.ndpl-page h5 { font-size: 16px; line-height: 24px; }
.ndpl-page h6 { font-size: 16px; line-height: 24px; }
}
/**
* #303637 - Heading color
* #616367 - Body color
* #B0B1B3 - Dimmed color
*
* Theme colors
* ----------------------------------------//
*/
.ndpl-c-background { background-color: #FFF; } /* Background color */
.ndpl-c-border { border-color: #E0E6ED; } /* Border color */
.ndpl-c-highlight { background-color: #F9FAFC; } /* Highlight background */
.ndpl-c-brand-c { color: #FEA1AC; } /* Brand color */
.ndpl-c-brand-bg { background-color: #FEA1AC; } /* Brand background color */
.ndpl-c-brand-b { border-color: #FEA1AC; } /* Brand border color */
.ndpl-c-brand-a:hover { color: #FEA1AC; } /* Brand anchor on hover */
.ndpl-c-brand-ca a,
.ndpl-c-brand-ca a[href],
.ndpl-c-brand-ca a[href]:focus,
.ndpl-c-brand-ca a:focus,
.ndpl-c-brand-ca a[href]:active,
.ndpl-c-brand-ca a:active,
.ndpl-c-brand-ca a[href]:visited,
.ndpl-c-brand-ca a:visited { color: #303637; } /* Brand child anchors */
.ndpl-c-brand-ca a[href]:hover,
.ndpl-c-brand-ca a:hover { color: #FEA1AC; } /* Brand child anchors on hover */
.ndpl-c-brand-cai a,
.ndpl-c-brand-cai a[href],
.ndpl-c-brand-cai a[href]:focus,
.ndpl-c-brand-cai a:focus,
.ndpl-c-brand-cai a[href]:active,
.ndpl-c-brand-cai a:active,
.ndpl-c-brand-cai a[href]:visited,
.ndpl-c-brand-cai a:visited { color: #FEA1AC; } /* Brand child anchors */
.ndpl-c-brand-cai a[href]:hover,
.ndpl-c-brand-cai a:hover { color: #303637 !important; } /* Brand child anchors on hover */
/**
* Helpers
* ----------------------------------------//
*/
/* No state change for anchors */
.ndpl-nsc,
.ndpl-nsc:focus,
.ndpl-nsc[href]:focus,
.ndpl-nsc:hover,
.ndpl-nsc[href]:hover,
.ndpl-nsc:active,
.ndpl-nsc[href]:active,
.ndpl-nsc:visited,
.ndpl-nsc[href]:visited {
color: #303637 !important;
text-decoration: none;
}
.ndpl-cf:after {
content: "";
display: block;
clear: both;
}
.ndpl-dark-text {
color: #616367 !important;
}
.ndpl-light-text {
color: #FFF !important;
}
.ndpl-apply-border {
border: 1px solid #E0E6ED;
}
.ndpl-apply-border + .ndpl-apply-border {
border-top: none;
}
/**
* Loading
* ----------------------------------------//
*/
.ndpl-loading__title {
color: #303637;
font-weight: 300;
margin: 0 24px 24px;
opacity: 0;
transition: opacity .5s ease;
}
.wf-opensans-n4-active .ndpl-loading__title {
opacity: 1;
}
.ndpl-container {
opacity: 0;
transition: opacity .5s ease .5s;
}
.ndpl-container.loaded {
opacity: 1;
}
.ndpl-container.resizing {
visibility: hidden;
}
.ndpl-loading {
left: -9999px;
opacity: 0;
padding: 96px 0;
position: fixed;
text-align: center;
transition: opacity .5s ease;
width: 100%;
}
.ndpl-loading.in-progress {
left: 0;
opacity: 1;
}
.ndpl-loading__title {
font-size: 27px;
padding-top: 24px;
}
@media only screen and (min-width: 60em) {
.ndpl-loading__title {
font-size: 36px;
padding-top: 24px;
}
}
/**
* Errors
* ----------------------------------------//
*/
.ndpl-error,
.ndpl-info {
border-radius: 6px;
color: #FFF;
display: inline-block;
list-style: none;
margin: 0 12px;
padding: 24px;
font-size: 14px;
}
.ndpl-error {
background-color: #f97d7d;
}
.ndpl-info {
background-color: #7da9f9;
}
.ndpl-error code,
.ndpl-info code {
padding: 0 3px;
}
.ndpl-error code { background-color: #e07070; }
.ndpl-info code { background-color: #7098e0; }
.ndpl-error .ndpl-pre,
.ndpl-info .ndpl-pre {
margin-bottom: 0;
}
@media only screen and (min-width: 60em) {
.ndpl-error,
.ndpl-info {
margin: 0;
}
}
/**
* Folding cube animation
* Created by Tobias Ahlin
* http://tobiasahlin.com/spinkit/
* ----------------------------------------//
*/
.ndpl-folding-cube {
margin: 20px auto;
width: 40px;
height: 40px;
position: relative;
-webkit-transform: rotateZ(45deg);
transform: rotateZ(45deg);
}
.ndpl-folding-cube .ndpl-cube {
float: left;
width: 50%;
height: 50%;
position: relative;
-webkit-transform: scale(1.1);
-ms-transform: scale(1.1);
transform: scale(1.1);
}
.ndpl-folding-cube .ndpl-cube:before {
content: '';
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
background-color: #303637;
-webkit-animation: ndpl-foldCubeAngle 2.4s infinite linear both;
animation: ndpl-foldCubeAngle 2.4s infinite linear both;
-webkit-transform-origin: 100% 100%;
-ms-transform-origin: 100% 100%;
transform-origin: 100% 100%;
}
.ndpl-folding-cube .ndpl-cube2 {
-webkit-transform: scale(1.1) rotateZ(90deg);
transform: scale(1.1) rotateZ(90deg);
}
.ndpl-folding-cube .ndpl-cube3 {
-webkit-transform: scale(1.1) rotateZ(180deg);
transform: scale(1.1) rotateZ(180deg);
}
.ndpl-folding-cube .ndpl-cube4 {
-webkit-transform: scale(1.1) rotateZ(270deg);
transform: scale(1.1) rotateZ(270deg);
}
.ndpl-folding-cube .ndpl-cube2:before {
-webkit-animation-delay: 0.3s;
animation-delay: 0.3s;
}
.ndpl-folding-cube .ndpl-cube3:before {
-webkit-animation-delay: 0.6s;
animation-delay: 0.6s;
}
.ndpl-folding-cube .ndpl-cube4:before {
-webkit-animation-delay: 0.9s;
animation-delay: 0.9s;
}
@-webkit-keyframes ndpl-foldCubeAngle {
0%, 10% {
-webkit-transform: perspective(140px) rotateX(-180deg);
transform: perspective(140px) rotateX(-180deg);
opacity: 0;
} 25%, 75% {
-webkit-transform: perspective(140px) rotateX(0deg);
transform: perspective(140px) rotateX(0deg);
opacity: 1;
} 90%, 100% {
-webkit-transform: perspective(140px) rotateY(180deg);
transform: perspective(140px) rotateY(180deg);
opacity: 0;
}
}
@keyframes ndpl-foldCubeAngle {
0%, 10% {
-webkit-transform: perspective(140px) rotateX(-180deg);
transform: perspective(140px) rotateX(-180deg);
opacity: 0;
} 25%, 75% {
-webkit-transform: perspective(140px) rotateX(0deg);
transform: perspective(140px) rotateX(0deg);
opacity: 1;
} 90%, 100% {
-webkit-transform: perspective(140px) rotateY(180deg);
transform: perspective(140px) rotateY(180deg);
opacity: 0;
}
}
/**
* Header
* ----------------------------------------//
*/
.ndpl-header {
background-color: #FFF;
border-bottom: 1px solid #DDD;
box-shadow: 0 0 1px rgba(0,0,0,0.1);
margin:0 0 36px;
padding: 12px;
position: fixed;
top: 0;
width: 100%;
z-index: 9998;
}
.ndpl-header:after {
display: none;
}
.ndpl-header__logo {
float: left;
height: 28px;
margin: 0 6px 0 0;
}
.ndpl-header__title {
color: #303637;
font-size: 18px;
font-weight: 700;
line-height: 28px;
float: left;
margin: 0;
}
.ndpl-header__title a {
display: none;
}
.ndpl-header__title a,
.ndpl-header__title a:hover {
text-decoration: none !important;
}
.ndpl-header__title small {
font-size: 60%;
font-weight: 300;
margin-left: 6px;
}
@media only screen and (min-width: 60em) {
.ndpl-header {
display: none;
}
.ndpl-header__title a {
display: block;
}
}
/**
* Sidebar
* ----------------------------------------//
*/
.ndpl-sidebar {
background-color: #FFF;
bottom: 0;
box-shadow: 1px 0 2px rgba(0,0,0,0.2);
height: 100%;
left: -100%;
overflow-y: auto;
overflow-x: hidden;
padding: 103px 0 24px;
position: fixed;
right: 0;
top: 0;
width: 100%;
z-index: 9997;
}
.ndpl-mobile .ndpl-sidebar {
transition: left .5s ease;
}
.ndpl-sidebar.open {
left: 0;
}
.ndpl-sidebar__header {
display: none;
}
.ndpl-sidebar__logo {
float: left;
margin: 0 0 24px 0;
height: 50px;
}
@media only screen and (min-width: 60em) {
.ndpl-sidebar {
background-color: #FFF;
bottom: 0;
display: block;
left: -264px;
padding: 0;
position: fixed;
top: 0;
width: 264px;
}
.loaded .ndpl-sidebar {
left: 0;
}
/**
* Sidebar - Header
* ----------------------------------------//
*/
.ndpl-sidebar__header {
display: block;
padding: 24px 24px 36px;
}
.ndpl-sidebar__title {
color: #303637;
clear: left;
display: block;
font-size: 18px;
line-height: 24px;
font-weight: 700;
margin: 0;
}
.ndpl-sidebar__title a {
text-decoration: none;
}
.ndpl-sidebar__title a:hover {
color: #FEA1AC;
}
.ndpl-sidebar__title small {
display: block;
font-size: 16px;
font-weight: 400;
}
}
/**
* Copyright info
* ----------------------------------------//
*/
.ndpl-copyright {
display: block;
padding: 0 24px 24px;
}
.ndpl-copyright p {
color: #B0B1B3;
font-size: 12px;
font-weight: 300;
line-height: 21px;
}
.ndpl-copyright p:last-of-type {
margin: 0;
}
.ndpl-copyright a {
text-decoration: none;
}
/**
* Navigation - Title
* ----------------------------------------//
*/
.ndpl-nav__title {
color: #303637;
font-size: 12px;
font-weight: 700;
letter-spacing: 1px;
margin: 0 0 21px;
padding: 0 24px;
text-transform: uppercase;
}
/**
* Navigation - Structure
* ----------------------------------------//
*/
.ndpl-nav__items {
border-top: 1px solid transparent;
font-size: 14px;
font-weight: 400;
line-height: 24px;
list-style: none;
margin: 0 0 72px;
padding: 0;
}
.ndpl-nav__item {
position: relative;
}
.ndpl-nav__item.active .ndpl-nav__group {
font-weight: 700;
}
.ndpl-nav__child-items {
display: none;
font-size: 14px;
list-style: none;
min-height: 0;
padding: 0;
margin: 0;
}
.active .ndpl-nav__child-items {
display: block;
}
.ndpl-nav__child-item {
border-bottom: 1px solid transparent;
border-radius: 4px;
}
/**
* Navigation - Page
* ----------------------------------------//
*/
.ndpl-nav__page {
border-bottom: 1px solid #E0E6ED;
border-left: 6px solid transparent;
cursor: pointer;
display: block;
font-weight: 400;
padding: 6px 24px 6px 18px;
position: relative;
text-decoration: none;
}
.ndpl-nav__page.active,
.ndpl-nav__page:hover {
border-left-color: #FEA1AC;
}
/**
* Navigation - Group
* ----------------------------------------//
*/
.ndpl-nav__group {
border-bottom: 1px solid #E0E6ED;
display: block;
font-weight: 400;
padding: 6px 24px;
position: relative;
text-decoration: none;
}
.ndpl-nav__group:after {
background: transparent url("data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI5IiBoZWlnaHQ9IjE1IiB2aWV3Qm94PSIwIDAgOSAxNSI+CiAgPGRlZnM+CiAgICA8c3R5bGU+CiAgICAgIC5jbH MtMSB7CiAgICAgICAgZmlsbDogIzIzMWYyMDsKICAgICAgICBmaWxsLXJ1bGU6IGV2ZW5vZGQ7CiAgICAgIH0KICAgIDwvc3R5bGU+CiAgPC9kZWZzPgogIDxwYXRoIGNsYXNzPSJjbHMtMSIgZD0iTTQ2MC40NDgsNDkxLjAwOUw0NjgsNDk4LjVsLTcuNTQ4LDcuNDkyTDQ1OSw1MDQuNTU3bDYuMS02LjA1NS02LjEtNi4wNTdaIiB0cmFuc2Zvcm09InRyYW5zbGF0ZSgtNDU5IC00OTEpIi8+Cjwvc3ZnPgo=") center no-repeat;
background-size: 100% auto;
content: "";
display: block;
height: 8px;
margin-top: -4px;
position: absolute;
right: 24px;
top: 50%;
transform: rotate(90deg);
transition: transform .25s ease;
width: 5px;
}
.active .ndpl-nav__group:after {
transform: rotate(-90deg);
}
/**
* Navigation - Component
* ----------------------------------------//
*/
.ndpl-nav__component {
border-left: 6px solid transparent;
color: #616367 !important;
display: block;
font-size: 14px;
font-weight: 300;
padding: 6px 24px 6px 30px;
text-decoration: none;
}
.ndpl-nav__component.active,
.ndpl-nav__component:hover {
border-left-color: #FEA1AC;
}
.ndpl-nav__arrow {
margin: -4px 0 0;
opacity: 0.25;
position: absolute;
right: 12px;
top: 18px;
width: 16px;
}
.active .ndpl-nav__arrow {
transform: rotate(180deg);
}
/*
* Navigation
* ----------------------------------------//
*/
.ndpl-nav-handle {
display: block;
cursor: pointer;
height: 27px;
overflow: hidden;
position: fixed;
right: 0;
transform: rotate(0deg);
transition: .5s ease-in-out;
top: 15px;
width: 48px;
z-index: 9999;
}
.ndpl-nav-handle.open {
position: fixed;
}
.ndpl-nav-handle__container {
padding: 12px 0 0;
}
.ndpl-nav-handle span {
background-color: #303637;
display: block;
height: 3px;
opacity: 1;
position: absolute;
right: 12px;
transform: rotate(0deg);
transition: .25s ease-in-out;
width: 27px;
}
.ndpl-nav-handle span:nth-child(1) {
top: 0px;
}
.ndpl-nav-handle span:nth-child(2) {
top: 9px;
}
.ndpl-nav-handle span:nth-child(3) {
top: 18px;
}
.ndpl-nav-handle.open span:nth-child(1) {
top: 11px;
transform: rotate(-45deg);
}
.ndpl-nav-handle.open span:nth-child(2) {
opacity: 0;
right: -60px;
}
.ndpl-nav-handle.open span:nth-child(3) {
top: 11px;
transform: rotate(45deg);
}
@media only screen and (min-width: 60em) {
.ndpl-nav-handle {
display: none;
}
}
/**
* Content containers
* ----------------------------------------//
*/
.ndpl-page,
.ndpl-library {
padding-top: 79px;
}
.ndpl-page {
color: #616367;
padding-left: 12px;
padding-right: 12px;
}
.ndpl-page h1,
.ndpl-page h2,
.ndpl-page h3,
.ndpl-page h4,
.ndpl-page h5,
.ndpl-page h6 {
color: #303637;
}
.ndpl-preloaded {
left: -9999px;
position: absolute;
top: -9999px;
}
@media only screen and (min-width: 35em) {
.ndpl-page {
max-width: 580px;
margin: 0 auto;
}
}
@media only screen and (min-width: 60em) {
.ndpl-page,
.ndpl-library {
margin: 0 auto;
padding: 56px 0;
}
.ndpl-page h1:first-child,
.ndpl-page h2:first-child,
.ndpl-page h3:first-child,
.ndpl-page h4:first-child,
.ndpl-page h5:first-child,
.ndpl-page h6:first-child,
.ndpl-library h1:first-child,
.ndpl-library h2:first-child,
.ndpl-library h3:first-child,
.ndpl-library h4:first-child,
.ndpl-library h5:first-child,
.ndpl-library h6:first-child {
margin-top: 0;
}
.ndpl-content {
padding: 36px 48px 36px 312px;
}
}
/**
* Component Group
* ----------------------------------------//
*/
.ndpl-library__group {
overflow: auto;
zoom: 1;
}
.ndpl-library__title {
color: #303637;
padding-left: 12px;
padding-right: 12px;
margin-bottom: 24px;
}
@media only screen and (min-width: 60em) {
.ndpl-library__title {
padding-left: 0;
padding-right: 0;
margin-bottom: 24px;
}
}
/**
* Group
* ----------------------------------------//
*/
.ndpl-group__description {
color: #616367;
margin-bottom: 48px;
padding: 0 12px;
}
@media only screen and (min-width: 60em) {
.ndpl-group__description {
padding: 0;
}
}
/**
* Component
* ----------------------------------------//
*/
.ndpl-component {
clear: both;
margin-bottom: 60px;
}
.ndpl-component__title,
.ndpl-component__description {
color: #616367;
padding: 0 12px;
}
.ndpl-component__title {
margin-bottom: 12px;
}
.ndpl-component__description {
padding-bottom: 24px;
}
@media only screen and (min-width: 60em) {
.ndpl-component__title,
.ndpl-component__description {
padding: 0;
}
}
/**
* Component - Half Width
* ----------------------------------------//
*/
@media only screen and (min-width: 60em) {
.ndpl-components {
display: -ms-flexbox;
display: -webkit-flex;
display: flex;
-ms-flex-direction: row;
-webkit-flex-direction: row;
flex-direction: row;
-ms-flex-wrap: wrap;
-webkit-flex-wrap: wrap;
flex-wrap: wrap;
margin-left: -36px;
}
.ndpl-component {
padding-left: 36px;
}
.ndpl-component--half {
-ms-flex-grow: 2;
-webkit-flex-grow: 2;
flex-grow: 2;
max-width: 50%;
width: 50%;
}
.ndpl-component--full {
-ms-flex-grow: 1;
-webkit-flex-grow: 1;
flex-grow: 1;
width: 100%;
}
}
/**
* Component - Colours
* ----------------------------------------//
*/
.ndpl-component__colors {
padding: 0 12px;
}
.ndpl-component__color-container {
float: left;
margin-top: 24px;
width: 100%;
}
.ndpl-component__color-container:first-of-type {
margin-top: 0;
}
.ndpl-component__color-container:nth-child(even) {
margin-right: 0;
}
.ndpl-component__color {
float: left;
line-height: 1;
padding: 24px 0;
text-align: center;
width: 50%;
}
.ndpl-component__color:first-of-type {
border-radius: 6px 0 0 6px;
}
.ndpl-component__color:last-of-type {
border-radius: 0 6px 6px 0;
}
.ndpl-component__color:first-of-type:last-of-type {
border-radius: 6px;
width: 100%;
}
.ndpl-component__color div {
border: 1px solid #FFF;
border-radius: 3px;
color: #FFF;
display: inline-block;
font-size: 13px;
letter-spacing: 1px;
line-height: 13px;
padding: 6px 9px;
text-transform: uppercase;
}
.ndpl-component__color div.ndpl-dark-text {
color: #B0B1B3 !important;
border-color: #B0B1B3;
}
@media only screen and (min-width: 60em) {
.ndpl-component__colors {
padding: 0;
}
.ndpl-component__color-container {
margin-right: 3%;
width: 17.5%;
}
.ndpl-component__color-container:nth-child(even) {
margin-right: 3%;
}
.ndpl-component__color-container:nth-child(5n) {
margin-right: 0;
}
.ndpl-component__color-container:nth-child(-n + 5) {
margin-top: 0;
}
.ndpl-component__color {
padding: 48px 0;
width: 100%;
}
.ndpl-component__color:first-of-type {
border-radius: 6px 6px 0 0;
}
.ndpl-component__color:last-of-type {
border-radius: 0 0 6px 6px;
}
}
/**
* Component - Preview & code sample
* ----------------------------------------//
*/
.ndpl-component__sample {
background-color: #FFF;
border-top: 1px solid #E0E6ED;
border-bottom: 1px solid #E0E6ED;
padding: 36px 12px;
position: relative;
}
.ndpl-component__sample:after {
display: block;
clear: both;
content: "";
}
.ndpl-component__sample--inverted {
background-color: #333;
}
.ndpl-component__sample-missing,
.ndpl-component__sample-hidden {
display: block;
margin: 0 12px;
text-align: center;
}
.ndpl-component__code {
border-bottom: 1px solid #E0E6ED;
}
.ndpl-component__code .ndpl-pre {
margin: 0;
}
/* We apply the same code styling to page, description and component elements. */
.ndpl-page pre code,
.ndpl-component__description pre code,
.ndpl-component__code .ndpl-code {
box-sizing: border-box;
color: #616367;
font-size: 12px;
line-height: 18px;
opacity: 0.75;
overflow-x: auto;
overflow-y: hidden;
-ms-overflow-style: -ms-autohiding-scrollbar;
padding: 36px 12px;
white-space: pre;
width: 100%;
}
.ndpl-page pre code,
.ndpl-component__description pre code {
padding: 12px;
}
.ndpl-component__code-toggle {
border-bottom: 1px solid transparent;
color: #B0B1B3;
cursor: pointer;
display: block;
font-size: 12px;
letter-spacing: 1px;
padding: 9px 12px 9px 12px;
text-align: center;
text-transform: uppercase;
}
@media only screen and (min-width: 60em) {
.ndpl-component__sample {
border: 1px solid #E0E6ED;
border-radius: 6px 6px 0 0;
padding: 36px;
}
.ndpl-component__sample--disabled-code {
border-radius: 6px;
}
.ndpl-component__sample-missing,
.ndpl-component__sample-hidden {
margin: 0;
}
.ndpl-component__code {
border: 1px solid #E0E6ED;
border-top: none;
}
.ndpl-page pre code,
.ndpl-component__description pre code,
.ndpl-component__code .ndpl-code {
font-size: 15px;
line-height: 21px;
padding: 36px;
}
.ndpl-page pre code,
.ndpl-component__description pre code {
padding: 12px;
}
.ndpl-component__code-toggle {
border-left: 1px solid transparent;
border-right: 1px solid transparent;
border-radius: 0 0 6px 6px;
}
}
================================================
FILE: pattern-library/app/js/main.js
================================================
/**
* Component component
*/
var ndplComponent = Vue.extend({
data: function() {
return {
loaded: false,
hide_sample_code: false
}
},
props: {
component: {
required: true
}
},
computed: {
inline_styles: function() {
var _this = this,
styles = '';
// These inline style are only applied after the component has fully loaded
if(_this.loaded) {
if(_this.component.options.sample_min_height) {
styles += 'min-height:' + _this.component.options.sample_min_height + 'px;';
}
}
if(_this.component.options.sample_overflow_hidden) {
styles += 'overflow: hidden;';
}
if(_this.component.options.sample_background_color) {
styles += 'background-color:' + _this.component.options.sample_background_color + ' !important;';
}
return styles;
}
},
watch: {
'component.html': function() {
var _this = this;
// Apply syntax highlighting when component html is loaded
if(this.component.html.length) {
_this.$root.applySyntaxHighlighting(_this.$el);
}
}
},
ready: function() {
var _this = this;
// Listen for loaded event
_this.$on('loaded', function() {
// Monitor scroll and resize events and update navigation active state appropirately
window.addEventListener('scroll', _this.updateActive);
window.addEventListener('resize', _this.updateActive);
_this.setHideSample(function() {
_this.loaded = true;
});
});
// Listen for resizing event
_this.$on('resizing', function(is_resizing) {
_this.loaded = false;
if(! is_resizing) {
_this.setHideSample(function() {
_this.loaded = true;
});
}
});
if (_this.component.html) {
_this.$root.applySyntaxHighlighting(_this.$el);
}
},
methods: {
/**
* Update component active in navigation.
*/
updateActive: function() {
var _this = this;
// If scroll position is great than or equal to component offset top - 60 pixels
// and scroll position is less than component offset top plus component height plus 60 pixels
// and active component is not this component
if(_this.$root && _this.$root.scroll_position >= _this.$el.offsetTop - 60 &&
_this.$root.scroll_position < _this.$el.offsetTop + _this.$el.offsetHeight) {
// If not currently auto scrolling to component
// and component is not active
if(!_this.$root.scrolling_to &&
!_this.isActive(_this.component)) {
// Set this component to active
_this.$root.active_components.push(_this.component);
_this.$root.open_group = null;
_this.$root.updateHash(_this.component.id);
}
} else {
// If not currently auto scrolling to component
if(_this.$root && !_this.$root.scrolling_to) {
// Loop through active components and remove this component
for (var i = 0; i < _this.$root.active_components.length; i++) {
var component = _this.$root.active_components[i];
if (component.id === _this.component.id) {
_this.$root.active_components.splice(i, 1);
return;
}
}
}
}
},
/**
* Is component active in navigation.
*
* @param component
* @returns {boolean}
*/
isActive: function(component) {
var _this = this;
for (var i = 0; i < _this.$root.active_components.length; i++) {
var c = _this.$root.active_components[i];
if (component.id === c.id) {
return true;
}
}
return false;
},
/**
* Should invert text based on hex brightness.
*
* @param hex
* @returns {boolean}
*/
shouldInvertText: function(hex) {
var rgb = this.$root.convertHexToRgb(hex),
brightness = this.$root.getColorBrightness(rgb);
return brightness > 210;
},
/**
* Should apply border based on hex brightness.
*
* @param hex
* @returns {boolean}
*/
shouldApplyBorder: function(hex) {
var rgb = this.$root.convertHexToRgb(hex),
brightness = this.$root.getColorBrightness(rgb);
return brightness > 240;
},
/**
* Set component sample element to be hidden if the sample
* itself is hidden in the assets CSS stylesheet.
*
* @param callback
*/
setHideSample: function(callback) {
callback = typeof callback !== 'undefined' ? callback : function() {};
var _this = this;
_this.hide_sample_code = false;
setTimeout(function() {
if(_this.$el.querySelector('.ndpl-component__code')) {
/**
* Auto-detect hidden sample.
*/
if (_this.$el.querySelector('.ndpl-component__sample').offsetHeight <= 74 &&
!_this.component.options.disabled_auto_sample_hiding) {
_this.hide_sample_code = true;
}
/**
* If manually specifying when to show nad hide samples.
*/
if (_this.component.options.disabled_auto_sample_hiding &&
_this.component.options.disabled_auto_sample_hiding.hasOwnProperty('show_on_mobile') &&
_this.component.options.disabled_auto_sample_hiding.hasOwnProperty('show_on_desktop')) {
if(_this.$root.mobile_view) {
_this.hide_sample_code = !_this.component.options.disabled_auto_sample_hiding.show_on_mobile;
} else {
_this.hide_sample_code = !_this.component.options.disabled_auto_sample_hiding.show_on_desktop;
}
}
}
callback();
}, 0);
},
/**
* Is sample code visible.
*
* @returns {boolean}
*/
isCodeVisible: function() {
var _this = this;
return ! _this.hide_sample_code;
}
}
});
Vue.component('ndpl-component', ndplComponent);
/**
* Group component
*/
var ndplGroup = Vue.extend({
props: {
group: {
required: true
}
}
});
Vue.component('ndpl-group', ndplGroup);
/**
* Script component
*/
var ndplScript = Vue.extend({
props: {
script: {
required: true
}
},
methods: {
/**
* Loads TypeKit.
*/
loadTypekit: function() {
try {
Typekit.load({
async: true
});
} catch(e) {};
}
}
});
Vue.component('ndpl-script', ndplScript);
/**
* Vue instance
*/
new Vue({
el: 'html',
data: {
intro: null,
project_logo: null,
project_favicon: null,
project_name: null,
project_url: null,
copyright_start_year: null,
client_name: null,
client_url: null,
creators: {},
content: {},
groups: {},
theme: {},
assets: {
css: [],
js: []
},
font_libraries: {
typekit_code: null,
google_web_fonts: null,
typography_web_fonts: null
},
log: {
error: [],
info: []
},
components_count: 0,
groups_count: 0,
components_loaded_count: 0,
groups_loaded_count: 0,
groups_loaded: false,
loaded: false,
resizing: false,
typekit_loaded: false,
scroll_position: 0,
prev_scroll_position: 0,
active_group: null,
active_components: [],
active_page: null,
open_group: null,
show_first_page_on_load: false,
scrolling_to: false,
sidebar_scrolling: false,
window_outer_width: 0,
breakpoint: 960,
mobile_view: false,
open_nav: false,
rtime: new Date(1, 1, 2000, 12,00,00),
timeout: false,
delta: 200,
version: null
},
computed: {
project: function() {
if(this.project_name && this.project_url) {
return '<a href="' + this.project_url + '" target="_blank"><span>' + this.project_name + '</span></a>';
}
if(this.project_name && !this.project_url) {
return this.project_name;
}
return null;
},
copyright_year: function() {
var date = new Date();
if(date.getFullYear() == this.copyright_start_year) {
return this.copyright_start_year;
}
return this.copyright_start_year + ' - ' + date.getFullYear();
},
client: function() {
if(this.client_name && this.client_url) {
return '<a href="' + this.client_url + '" target="_blank">' + this.client_name + '</a>';
}
if(this.client_name && !this.client_url) {
return this.client_name;
}
return null;
},
all_creators: function() {
var formattedCreators = '';
if(this.creators.length && this.creators[0].name) {
for (var i = 0; i < this.creators.length; i++) {
prefix = i === this.creators.length - 1 ? ' & ' : ', ';
url = this.creators[i].url;
name = this.creators[i].name.replace(' ', ' ');
formattedCreators += prefix + '<a href="' + url + '" target="_blank">' + name + '</a>';
}
return formattedCreators.substring(2);
}
return null;
},
library_inline_styles: function() {
var _this = this,
styles = '';
if(_this.theme.max_width) {
styles += 'max-width:' + _this.theme.max_width + 'px;';
}
return styles;
}
},
watch: {
groups_loaded: function() {
var _this = this;
_this.setupComponents();
},
loaded: function() {
var _this = this;
_this.scrollTo(window.location.hash);
_this.$broadcast('loaded');
}
},
ready: function() {
var _this = this;
_this.loadDataFile();
_this.window_outer_width = window.outerWidth;
_this.mobile_view = _this.window_outer_width >= _this.breakpoint ? false : true;
window.addEventListener('scroll', _this.setScrollPosition);
window.addEventListener('resize', function() {
_this.window_outer_width = window.outerWidth;
_this.setScrollPosition();
_this.mobile_view = _this.window_outer_width >= _this.breakpoint ? false : true;
_this.rtime = new Date();
if (_this.timeout === false && !_this.mobile_view) {
_this.timeout = true;
setTimeout(_this.trackResizing, _this.delta);
}
});
/**
* Disable body scrolling when mouseover/mouseleave
* sidebar to prevent library scroll jumping.
*/
var sidebar = document.querySelector('.ndpl-sidebar');
sidebar.addEventListener('mouseover', function(e) {
_this.sidebar_scrolling = true;
})
sidebar.addEventListener('mouseleave', function(e) {
_this.sidebar_scrolling = false;
});
/**
* Set active page based on hash or show first
* page on load variable.
*/
setTimeout(function() {
var page = _this.isLoadingPage();
if(page) {
_this.loadPage(page);
}
}, 0);
},
methods: {
/**
* Apply syntax highlighting to pre code elements
* within passed element.
*
* @param el
*/
applySyntaxHighlighting: function(el) {
setTimeout(function() {
var blocks = el.querySelectorAll('pre code');
for(var i = 0; i < blocks.length; i++) {
var block = blocks[i];
hljs.highlightBlock(block);
}
}, 0);
},
/**
* Reads the data.json file.
*/
loadDataFile: function () {
var _this = this;
_this.$http.get('./data.json' + '?cb=' + new Date()).then(function (response) {
_this.initData(response.data, function() {
if(_this.$data.groups.length) {
_this.setupGroups();
} else {
_this.logInfo('You need to add a component to your library before it can be loaded.<br/>You can either do this manually by editing your <code>data.json</code> file,<br/> or you can use the command line helper: <code>astrum new [group_name/component_name]</code>');
}
});
});
},
/**
* Determine if a page should be loaded.
*/
isLoadingPage: function() {
var _this = this,
hash = location.hash;
if(_this.content.pages !== undefined && _this.content.pages.length) {
if(hash) {
for (var i = 0; i < _this.content.pages.length; i++) {
var page = _this.content.pages[i];
if (page.name == hash.replace('#', '')) return page;
}
} else if(_this.content.show_first_page_on_load) {
return _this.content.pages[0];
}
}
return false;
},
/**
* Initilise data bindings.
*
* @param data
*/
initData: function(data, callback) {
callback = typeof callback !== 'undefined' ? callback : function() {};
var _this = this;
for(var key in data) {
_this.$set(key, data[key]);
}
callback();
},
/**
* Update URL hash.
*
* @param hash
*/
updateHash: function(hash) {
history.pushState ? history.pushState(null, null, '#' + hash) : location.hash = hash;
},
/**
* Setup component groups.
*/
setupGroups: function() {
var _this = this;
// Loop through the groups
for (var i = 0; i < _this.groups.length; i++) {
var group = _this.groups[i];
// Set group navigation navigation
_this.$set('groups[' + i + '].id', 'group-' + group.name);
_this.$set('groups[' + i + '].active', false);
// Set default variables
_this.$set('groups[' + i + '].description', '');
// Count groups
_this.groups_count = _this.groups.length;
// Load group
_this.loadGroup(_this.groups[i]);
}
},
setupComponents: function() {
var _this = this;
// Loop through the components
for (var i = 0; i < _this.groups.length; i++) {
var group = _this.groups[i];
// Count components
_this.components_count += group.components.length;
// Add group components to group
for (var j = 0; j < group.components.length; j++) {
// Set default variables
_this.$set('groups[' + i + '].components[' + j + '].id', 'group-' + group.name + '-component-' + group.components[j].name);
_this.$set('groups[' + i + '].components[' + j + '].group_id', 'group-' + group.name);
_this.$set('groups[' + i + '].components[' + j + '].active', false);
_this.$set('groups[' + i + '].components[' + j + '].options', group.components[j].options ? group.components[j].options : false);
_this.$set('groups[' + i + '].components[' + j + '].options.sample_always_show', group.components[j].options.sample_always_show ? group.components[j].options.sample_always_show : false);
_this.$set('groups[' + i + '].components[' + j + '].options.sample_mobile_hidden', group.components[j].options.sample_mobile_hidden ? group.components[j].options.sample_mobile_hidden : false);
_this.$set('groups[' + i + '].components[' + j + '].options.sample_dark_background', group.components[j].options.sample_dark_background ? group.components[j].options.sample_dark_background : false);
_this.$set('groups[' + i + '].components[' + j + '].options.disable_code_sample', group.components[j].options.disable_code_sample ? group.components[j].options.disable_code_sample : false);
_this.$set('groups[' + i + '].components[' + j + '].code_show', false);
_this.$set('groups[' + i + '].components[' + j + '].type', group.components[j].type ? group.components[j].type : 'standard');
_this.$set('groups[' + i + '].components[' + j + '].width', group.components[j].width ? group.components[j].width : 'full');
// Add html and description properties to the component object.
_this.$set('groups[' + i + '].components[' + j + '].html', '');
_this.$set('groups[' + i + '].components[' + j + '].description', '');
_this.loadComponent(_this.groups[i].components[j]);
}
}
},
/**
* Load group files.
*
* @param group
*/
loadGroup: function(group) {
var _this = this,
group_path = './components/' + group.name;
// Get and set component description
_this.$http.get(group_path + '/description.md' + '?cb=' + new Date()).then(function (response) {
group.description = marked(response.data);
_this.areGroupsLoaded();
}, function () {
_this.logError('Description file for <strong>' + group.name + '</strong> group failed to load from <code>' + group_path + '/description.md</code>');
});
},
/**
* Load component files.
*
* @param component
*/
loadComponent: function(component) {
var _this = this,
component_path = './components/' + component.group + '/' + component.name;
// Get and set component markup
_this.$http.get(component_path + '/markup.html' + '?cb=' + new Date()).then(function (response) {
component.html = response.data;
_this.areComponentsLoaded();
}, function () {
_this.logError('HTML file for <strong>' + component.name + '</strong> component failed to load from <code>' + component_path + '/html.md</code>');
});
// Get and set component description
_this.$http.get(component_path + '/description.md' + '?cb=' + new Date()).then(function (response) {
component.description = marked(response.data);
_this.areComponentsLoaded();
}, function () {
_this.logError('Description file for <strong>' + component.name + '</strong> component failed to load from <code>' + component_path + '/description.md</code>');
});
},
/**
* Increment groups loaded.
*/
areGroupsLoaded: function() {
var _this = this;
_this.groups_loaded_count += 1;
if (_this.groups_loaded_count === _this.groups_count) {
setTimeout(function() {
_this.groups_loaded = true;
}, 1000);
}
},
/**
* Increment components loaded.
*/
areComponentsLoaded: function() {
var _this = this;
_this.components_loaded_count += 1;
if (_this.components_loaded_count === _this.components_count * 2) {
setTimeout(function() {
_this.loaded = true;
}, 2000);
}
},
/**
* Add to log.
*
* @param message
* @param data
* @param type
*/
addLog: function(message, data, type) {
var _this = this;
type = typeof type !== 'undefined' ? type : 'error';
data = typeof data !== 'undefined' ? data : null;
_this.log[type].push(message);
console[type]('[Pattern Library warn]: ' + message);
if(data) {
console[type](data);
}
},
/**
* Log error helper.
*
* @param message
* @param data
*/
logError: function(message, data) {
var _this = this;
_this.addLog(message, data, 'error');
},
/**
* Log info helper.
*
* @param message
* @param data
*/
logInfo: function(message, data) {
var _this = this;
_this.addLog(message, data, 'info');
},
/**
* Set scroll position.
*/
setScrollPosition: function() {
var _this = this,
doc = document.documentElement,
top = doc && doc.scrollTop || document.body.scrollTop;
_this.prev_scroll_position = _this.scroll_position;
_this.scroll_position = top;
},
/**
* Get scroll direction.
*
* @returns {string}
*/
getScrollDirection: function() {
var _this = this;
return _this.prev_scroll_position < _this.scroll_position ? 'down' : 'up';
},
/**
* Scroll to element.
*
* @param e
*/
scrollToHref: function(e) {
var _this = this;
_this.scrollTo(e.target.hash);
_this.active_page = null;
},
/**
* Animate scroll to.
*
* @param hash
*/
scrollTo: function(hash) {
var _this = this,
offset = _this.mobile_view ? 79 : 30;
if(!hash) return;
_this.scrolling_to = true;
smoothScroll.animateScroll(hash, null, {
offset: offset,
callback: function() {
_this.scrolling_to = false;
_this.open_nav = false;
}
});
},
/**
* Toggle navigation.
*/
toggleNav: function() {
var _this = this;
_this.open_nav = ! _this.open_nav;
},
/**
* Toggle open groups.
*
* @param group
*/
toggleOpenGroups: function(group) {
var _this = this;
_this.open_group = _this.open_group == group.id ? null : group.id;
_this.active_page = null;
},
/**
* Load content page.
* @param page
*/
loadPage: function(page) {
var _this = this;
_this.active_page = page;
_this.active_components = [];
_this.open_group = null;
_this.open_nav = false;
_this.$http.get(page.file + '?cb=' + new Date()).then(function (response) {
_this.$set('active_page.markup', marked(response.data));
_this.applySyntaxHighlighting(document);
});
_this.updateHash(page.name);
},
/**
* Track resizing and broadcast resizing events.
*/
trackResizing: function() {
var _this = this;
_this.resizing = true;
_this.$broadcast('resizing', true);
if (new Date() - _this.rtime < _this.delta) {
setTimeout(_this.trackResizing, _this.delta);
} else {
_this.timeout = false;
setTimeout(function() {
_this.resizing = false;
_this.$broadcast('resizing', false);
}, 1000);
}
},
/**
* Convert hex color value to rgb color values.
*
* @param hex
* @returns {{r: number, g: number, b: number}}
*/
convertHexToRgb: function(hex) {
// Expand shorthand form (e.g. "03F") to full form (e.g. "0033FF")
var shorthandRegex = /^#?([a-f\d])([a-f\d])([a-f\d])$/i;
hex = hex.replace(shorthandRegex, function(m, r, g, b) {
return r + r + g + g + b + b;
});
var result = /^#?([a-f\d]{2})([a-f\d]{2})([a-f\d]{2})$/i.exec(hex);
return result ? {
r: parseInt(result[1], 16),
g: parseInt(result[2], 16),
b: parseInt(result[3], 16)
} : null;
},
/**
* Get color brightness value from rgb color values.
*
* @param rgb
* @returns {number}
*/
getColorBrightness: function(rgb) {
return Math.round(((parseInt(rgb.r) * 299) + (parseInt(rgb.g) * 587) + (parseInt(rgb.b) * 114)) /1000);
}
}
});
================================================
FILE: pattern-library/assets/js/patterns.js
================================================
(function() {
var componentSamples = [].slice.call(document.querySelectorAll('.ndpl-component__sample'));
if(componentSamples.length) {
componentSamples.map(function(item) {
item.classList.add('boilerform');
});
}
}());
================================================
FILE: pattern-library/components/button/default/description.md
================================================
================================================
FILE: pattern-library/components/button/default/markup.html
================================================
<button class="c-button">A button</button>
================================================
FILE: pattern-library/components/button/description.md
================================================
================================================
FILE: pattern-library/components/check-field/checkbox/description.md
================================================
================================================
FILE: pattern-library/components/check-field/checkbox/markup.html
================================================
<div class="c-check-field">
<input type="checkbox" name="checkbox-field" id="checkbox-field" class="c-check-field__input" />
<label for="checkbox-field" class="c-check-field__decor" aria-hidden="true" role="presentation"></label>
<label for="checkbox-field" class="c-check-field__label">A checkbox field</label>
</div>
================================================
FILE: pattern-library/components/check-field/description.md
================================================
================================================
FILE: pattern-library/components/check-field/error-state/description.md
================================================
================================================
FILE: pattern-library/components/check-field/error-state/markup.html
================================================
<div class="[ c-check-field ] [ is-error ]">
<input type="checkbox" name="checkbox-error-field" id="checkbox-error-field" class="c-check-field__input" />
<label for="checkbox-error-field" class="c-check-field__decor" aria-hidden="true" role="presentation"></label>
<label for="checkbox-error-field" class="c-check-field__label">A checkbox field</label>
</div>
<div class="[ c-check-field c-check-field--radio ] [ is-error ]">
<input type="radio" name="radio-error-field" id="radio-error-field" class="c-check-field__input" />
<label for="radio-error-field" class="c-check-field__decor" aria-hidden="true" role="presentation"></label>
<label for="radio-error-field" class="c-check-field__label">A radio button</label>
</div>
================================================
FILE: pattern-library/components/check-field/radio/description.md
================================================
================================================
FILE: pattern-library/components/check-field/radio/markup.html
================================================
<div class="c-check-field c-check-field--radio">
<input type="radio" name="checkbox-field" id="checkbox-radio-field-1" class="c-check-field__input" />
<label for="checkbox-radio-field-1" class="c-check-field__decor" aria-hidden="true" role="presentation"></label>
<label for="checkbox-radio-field-1" class="c-check-field__label">A radio button</label>
</div>
<div class="c-check-field c-check-field--radio">
<input type="radio" name="checkbox-field" id="checkbox-radio-field-2" class="c-check-field__input" />
<label for="checkbox-radio-field-2" class="c-check-field__decor" aria-hidden="true" role="presentation"></label>
<label for="checkbox-radio-field-2" class="c-check-field__label">Another radio button</label>
</div>
================================================
FILE: pattern-library/components/input-field/description.md
================================================
Generic input fields with variations for size, placeholders and validation states. Relevant attributes are added to help users input data as efficiently as possible.
================================================
FILE: pattern-library/components/input-field/email/description.md
================================================
================================================
FILE: pattern-library/components/input-field/email/markup.html
================================================
<input type="email" name="" id="" autocapitalize="none" autocorrect="off" class="c-input-field" value="user@email.com" />
================================================
FILE: pattern-library/components/input-field/error-state/description.md
================================================
================================================
FILE: pattern-library/components/input-field/error-state/markup.html
================================================
<input type="text" name="" id="" class="[ c-input-field ] [ is-error ]" value="Generic text" />
================================================
FILE: pattern-library/components/input-field/number/description.md
================================================
================================================
FILE: pattern-library/components/input-field/number/markup.html
================================================
<input type="number" name="" id="" min="1" max="999" step="1" class="c-input-field" value="123" />
================================================
FILE: pattern-library/components/input-field/search/description.md
================================================
================================================
FILE: pattern-library/components/input-field/search/markup.html
================================================
<input type="search" name="" id="" autocorrect="off" class="c-input-field" value="Some search terms" />
================================================
FILE: pattern-library/components/input-field/tel/description.md
================================================
================================================
FILE: pattern-library/components/input-field/tel/markup.html
================================================
<input type="tel" name="" id="" class="c-input-field" value="01234 567 890" />
================================================
FILE: pattern-library/components/input-field/text/description.md
================================================
================================================
FILE: pattern-library/components/input-field/text/markup.html
================================================
<input type="text" name="" id="" class="c-input-field" value="Generic text" />
================================================
FILE: pattern-library/components/input-field/text-area/description.md
================================================
================================================
FILE: pattern-library/components/input-field/text-area/markup.html
================================================
<textarea name="" id="" class="c-input-field c-input-field--multiline">Some multiline text</textarea>
================================================
FILE: pattern-library/components/label/default/description.md
================================================
================================================
FILE: pattern-library/components/label/default/markup.html
================================================
<label for="" class="c-label">A label for a field</label>
<input class="c-input-field" value="fdsfds" />
================================================
FILE: pattern-library/components/label/description.md
================================================
================================================
FILE: pattern-library/components/select-field/description.md
================================================
================================================
FILE: pattern-library/components/select-field/error-state/description.md
================================================
================================================
FILE: pattern-library/components/select-field/error-state/markup.html
================================================
<div class="[ c-select-field ] [ is-error ]">
<select name="" id="" class="c-select-field__menu">
<option>Select an item</option>
<option value="1">Item 1</option>
<option value="2">Item 2</option>
<option value="3">Item 3</option>
<option value="4">Item 5</option>
</select>
<span class="c-select-field__decor" aria-hidden="true" role="presentation">▾</span>
</div>
================================================
FILE: pattern-library/components/select-field/select-menu/description.md
================================================
================================================
FILE: pattern-library/components/select-field/select-menu/markup.html
================================================
<div class="c-select-field">
<select name="" id="" class="c-select-field__menu">
<option>Select an item</option>
<option value="1">Item 1</option>
<option value="2">Item 2</option>
<option value="3">Item 3</option>
<option value="4">Item 5</option>
</select>
<span class="c-select-field__decor" aria-hidden="true" role="presentation">▾</span>
</div>
================================================
FILE: pattern-library/data.json
================================================
{
"project_logo": "/assets/images/logo/logo.svg",
"project_favicon": "favicon.png",
"project_name": "Boilerform",
"project_url": null,
"copyright_start_year": null,
"client_name": null,
"client_url": null,
"creators": [
{
"name": "Boilerform site",
"url": "//boilerform.hankchizljaw.com"
},
{
"name": "Boilerform repo",
"url": "//github.com/hankchizljaw/boilerform"
},
{
"name": "By hankchizljaw",
"url": "//hankchizljaw.com"
}
],
"theme": {
"border_color": "#E0E6ED",
"highlight_color": "#F9FAFC",
"brand_color": "#A03EA0",
"background_color": "#FFFFFF",
"code_highlight_theme": "github",
"override_code_highlight_bg": "#F9FAFC",
"sample_dark_background": "#333333",
"show_project_name": false,
"show_version": true,
"max_width": null,
"titles": {
"library_title": "Patterns",
"pages_title": "Overview",
"components_title": "Components"
}
},
"assets": {
"css": [
"https://cdn.statically.io/gh/hankchizljaw/boilerform/70a13a07/dist/css/boilerform.min.css"
],
"js": [
"/assets/js/patterns.js?v=1.1.1"
]
},
"font_libraries": {
"typekit_code": null,
"typography_web_fonts": null,
"google_web_fonts": null
},
"content": null,
"groups": [
{
"name": "input-field",
"title": "Input Field",
"components": [
{
"group": "input-field",
"name": "text",
"title": "Text",
"width": "half"
},
{
"group": "input-field",
"name": "email",
"title": "Email",
"width": "half"
},
{
"group": "input-field",
"name": "search",
"title": "Search",
"width": "half"
},
{
"group": "input-field",
"name": "number",
"title": "Number",
"width": "half"
},
{
"group": "input-field",
"name": "tel",
"title": "Tel",
"width": "half"
},
{
"group": "input-field",
"name": "text-area",
"title": "Textarea / Multiline",
"width": "half"
},
{
"group": "input-field",
"name": "error-state",
"title": "Error State",
"width": "half"
}
]
},
{
"name": "select-field",
"title": "Select Field",
"components": [
{
"group": "select-field",
"name": "select-menu",
"title": "Select Menu",
"width": "half"
},
{
"group": "select-field",
"name": "error-state",
"title": "Error State",
"width": "half"
}
]
},
{
"name": "check-field",
"title": "Check Field",
"components": [
{
"group": "check-field",
"name": "checkbox",
"title": "Checkbox",
"width": "half"
},
{
"group": "check-field",
"name": "radio",
"title": "Radio",
"width": "half"
},
{
"group": "check-field",
"name": "error-state",
"title": "Error State",
"width": "half"
}
]
},
{
"name": "button",
"title": "Button",
"components": [
{
"group": "button",
"name": "default",
"title": "Default",
"width": "half"
}
]
},
{
"name": "label",
"title": "Label",
"components": [
{
"group": "label",
"name": "default",
"title": "Default",
"width": "half"
}
]
}
],
"version": "1.9.5"
}
================================================
FILE: pattern-library/index.html
================================================
<!DOCTYPE html>
<html lang="en" class="ndpl-c-background">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width">
<title v-text="project_name ? project_name + ' | Pattern Library' : 'Pattern Library'"></title>
<!-- Astrum (https://github.com/NoDivide/astrum) -->
<meta name="application-name" content="Astrum {{ version }}" />
<!-- Favicon -->
<link rel="shortcut icon" type="image/png" :href="project_favicon" />
<!-- Pattern Library Stylesheets: DO NOT CHANGE -->
<link href="https://fonts.googleapis.com/css?family=Open+Sans:300,400,600,700" rel='stylesheet' type='text/css'>
<script src="https://ajax.googleapis.com/ajax/libs/webfont/1.6.16/webfont.js"></script>
<script>
WebFont.load({
google: {
families: ['Open Sans']
}
});
</script>
<style>
/* Targeted theme styles */
.ndpl-folding-cube .ndpl-cube:before { background-color: {{ theme.brand_color }} !important; }
.ndpl-component__sample--inverted { background-color: {{ theme.sample_dark_background }} !important }
.ndpl-c-background { background-color: {{ theme.background_color }} !important; }
.ndpl-c-border { border-color: {{ theme.border_color }} !important; }
.ndpl-c-border-b { border-bottom-color: {{ theme.border_color }} !important; }
.ndpl-c-highlight { background-color: {{ theme.highlight_color }} !important; }
.ndpl-c-highlight-ca a.active,
.ndpl-c-highlight-ca a:hover { background-color: {{ theme.highlight_color }} !important; }
.ndpl-c-brand-c { color: {{ theme.brand_color }} !important; }
.ndpl-c-brand-bg { background-color: {{ theme.brand_color }} !important; }
.ndpl-c-brand-b { border-color: {{ theme.brand_color }} !important; }
.ndpl-c-brand-bl-ca a.active,
.ndpl-c-brand-bl-ca a:hover { border-left-color: {{ theme.brand_color }} !important; }
.ndpl-c-brand-a:hover { color: {{ theme.brand_color }} !important; }
.ndpl-c-brand-ca a:hover { color: {{ theme.brand_color }} !important; }
.ndpl-c-brand-cai a { color: {{ theme.brand_color }} !important; }
</style>
<link rel="stylesheet" v-if="theme.code_highlight_theme" :href="'https://cdnjs.cloudflare.com/ajax/libs/highlight.js/9.12.0/styles/' + theme.code_highlight_theme + '.min.css'">
<style v-if="theme.override_code_highlight_bg">.hljs { background: {{ theme.override_code_highlight_bg }}} !important; }</style>
<link rel="stylesheet" href="app/css/styles.min.css">
<!-- Font Libraries -->
<link rel="stylesheet" v-if="font_libraries.google_web_fonts" :href="font_libraries.google_web_fonts">
<link rel="stylesheet" v-if="font_libraries.typography_web_fonts" :href="font_libraries.typography_web_fonts">
<ndpl-script :script="'https://use.typekit.net/' + font_libraries.typekit_code + '.js'" v-if="font_libraries.typekit_code" inline-template>
<script :src="script" @load="loadTypekit"></script>
</ndpl-script>
<!-- Custom stylesheets are loaded from the assets.css array in data.json -->
<link rel="stylesheet" v-for="css in assets.css" :href="css">
</head>
<body id="top"
class="ndpl-body ndpl-c-background"
:class="{ 'ndpl-inverted': theme.invert_text, 'ndpl-desktop': !mobile_view, 'ndpl-mobile': mobile_view, 'ndpl-disable-scrolling': sidebar_scrolling }">
<div class="ndpl-loading" :class="{ 'in-progress': ! loaded }">
<div class="ndpl-folding-cube" v-if="!log.error.length && !log.info.length">
<div class="ndpl-cube1 ndpl-cube"></div>
<div class="ndpl-cube2 ndpl-cube"></div>
<div class="ndpl-cube4 ndpl-cube"></div>
<div class="ndpl-cube3 ndpl-cube"></div>
</div>
<h3 class="ndpl-loading__title" v-if="! loaded && !log.error.length && !log.info.length">Building pattern library...</h3>
<h3 class="ndpl-loading__title" v-if="log.error.length">Hold up! We have some errors...</h3>
<h3 class="ndpl-loading__title" v-if="log.info.length && !log.error.length">Looks like you have some setup to do...</h3>
<ul class="ndpl-error" v-if="log.error.length">
<li class="ndpl-error__item" v-for="error in log.error">{{{ error }}}</li>
</ul>
<ul class="ndpl-info" v-if="log.info.length && !log.error.length">
<li class="ndpl-info__item" v-for="info in log.info">{{{ info }}}</li>
</ul>
</div>
<div class="ndpl-container"
:class="{ 'loaded': loaded }">
<header class="ndpl-header">
<img class="ndpl-header__logo"
:src="project_logo"
:alt="project_name"
v-if="project_logo"/>
<h1 class="ndpl-header__title ndpl-c-brand-ca">
<span v-if="theme.show_project_name">{{{ project }}}</span>
<small v-if="theme.titles.library_title"
v-text="theme.titles.library_title"></small>
</h1>
<div class="ndpl-nav-handle"
:class="{ 'open': open_nav }"
@click="toggleNav">
<div class="ndpl-nav-handle__container">
<span></span>
<span></span>
<span></span>
</div>
</div>
</header>
<div class="ndpl-sidebar"
:class="{ 'open': open_nav }">
<header class="ndpl-sidebar__header">
<img class="ndpl-sidebar__logo"
:src="project_logo"
:alt="project_name"
v-if="project_logo"/>
<h1 class="ndpl-sidebar__title ndpl-c-brand-ca">
<span v-if="theme.show_project_name">{{{ project }}}</span>
<small v-if="theme.titles.library_title"
v-text="theme.titles.library_title"></small>
</h1>
</header>
<nav class="ndpl-nav">
<template v-if="content">
<h2 class="ndpl-nav__title"
v-if="theme.titles.pages_title"
v-text="theme.titles.pages_title"></h2>
<ul class="ndpl-nav__items ndpl-c-border ndpl-c-highlight-ca ndpl-c-brand-bl-ca">
<li class="ndpl-nav__item" v-for="page in content.pages">
<a class="ndpl-nav__page ndpl-nsc ndpl-c-border-b"
:class="{ 'active': active_page && active_page.title === page.title }"
v-text="page.title"
@click.prevent="loadPage(page)">
</a>
</li>
</ul>
</template>
<h2 class="ndpl-nav__title">
<a class="ndpl-nsc"
href="#top"
@click.prevent="scrollToHref"
v-if="theme.titles.components_title"
v-text="theme.titles.components_title"></a>
</h2>
<ul class="ndpl-nav__items ndpl-c-border">
<li class="ndpl-nav__item"
v-for="group in groups"
:class="{ 'active': active_components.length > 0 && group.id == active_components[0].group_id || group.id == open_group }">
<a :href="'#' + group.id"
class="ndpl-nav__group ndpl-nsc ndpl-c-border-b"
v-text="group.title"
@click.prevent="toggleOpenGroups(group)">
</a>
<ul class="ndpl-nav__child-items ndpl-c-highlight"
v-if="group.components.length">
<li class="ndpl-nav__child-item ndpl-c-border-b ndpl-c-brand-bl-ca"
v-for="component in group.components">
<a :href="'#' + component.id"
class="ndpl-nav__component ndpl-nsc"
:class="{ 'active': active_components.indexOf(component) >= 0 }"
v-text="component.title"
@click.prevent="scrollToHref">
</a>
</li>
</ul>
</li>
</ul>
</nav>
<div class="ndpl-copyright ndpl-c-brand-ca">
<p v-if="copyright_start_year && client || all_creators">
<template v-if="copyright_start_year && client">
© {{ copyright_year }} {{{ client }}}.
</template>
<template v-if="all_creators">
<br/>Pattern library created by {{{ all_creators }}}.
</template>
</p>
<p v-if="theme.show_version">Astrum v{{ version }}</p>
</div>
</div>
<div class="ndpl-content" data-app="astrum">
<div class="ndpl-page ndpl-c-brand-cai" :style="library_inline_styles" v-if="active_page">{{{ active_page.markup }}}</div>
<div class="ndpl-library" :style="library_inline_styles" :class="{ 'ndpl-preloaded': active_page }">
<ndpl-group v-for="group in groups"
:group="group"
inline-template>
<div class="ndpl-library__group"
:id="group.id">
<h2 class="ndpl-library__title">{{ group.title }}</h2>
<div class="ndpl-group__description ndpl-c-brand-ca"
v-html="group.description"
v-if="group.description"></div>
<div class="ndpl-components">
<ndpl-component v-for="component in group.components"
:component="component"
inline-template>
<div class="ndpl-component"
:id="component.id"
:group-id="component.group_id"
:class="'ndpl-component--' + component.width">
<h3 class="ndpl-component__title">{{ component.title }}</h3>
<div class="ndpl-component__description ndpl-c-brand-ca"
v-html="component.description"></div>
<template v-if="component.type == 'colors'">
<div v-if="component.colors.length" class="ndpl-component__colors ndpl-cf">
<div class="ndpl-component__color-container"
v-for="color in component.colors">
<div class="ndpl-component__color"
v-for="item in color.split(',')"
:class="{ 'ndpl-apply-border ndpl-c-border': shouldApplyBorder(item), }"
:style="'background-color:' + item">
<div :class="{ 'ndpl-dark-text': shouldInvertText(item) }">{{ item }}</div>
</div>
</div>
</div>
<ul v-else class="ndpl-component__sample-missing ndpl-info">
<li class="ndpl-info__item">Locate this component in your <code>data.json</code> file and add your colors to the "colors" array that has been created for you e.g.:</li>
<li><pre class="ndpl-pre">"colors": ["#4c4c4c","#7d8284","#a6b1b5","#e6eaf2","#FFFFFF"]</pre></li>
</ul>
</template>
<template v-else>
<div class="ndpl-component__container"
v-show="isCodeVisible()">
<div class="ndpl-component__sample ndpl-c-border"
:class="{
'ndpl-component__sample--inverted': component.options.sample_dark_background,
'ndpl-component__sample--disabled-code': component.options.disable_code_sample
}"
:style="inline_styles"
v-if="component.html">
{{{ component.html }}}
</div>
<template v-if="component.html">
<div class="ndpl-component__code ndpl-c-border"
v-show="component.code_show">
<pre class="ndpl-pre"><code class="ndpl-code html" v-text="component.html"></code></pre>
</div>
<a v-if="!component.options.disable_code_sample"
class="ndpl-component__code-toggle ndpl-c-highlight ndpl-c-border"
@click.prevent="component.code_show = ! component.code_show"
v-text="component.code_show ? 'Hide code sample' : 'Show code sample'"></a>
</template>
<ul v-else class="ndpl-component__sample-missing ndpl-info">
<li class="ndpl-info__item">Add your component markup to <code>/components/{{ component.group }}/{{ component.name }}/markup.html</code></li>
</ul>
</div>
<div class="ndpl-component__sample-hidden ndpl-info"
v-show="!isCodeVisible()">
This component is hidden at this resolution.
</div>
</template>
</div>
</ndpl-component>
</div>
</div>
</ndpl-group>
</div>
</div>
</div>
<ndpl-script v-for="script in assets.js"
:script="script"
v-if="loaded"
inline-template>
<script :src="script"></script>
</ndpl-script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/1.0.25/vue.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue-resource/0.8.0/vue-resource.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/9.12.0/highlight.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/marked/0.3.5/marked.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/smooth-scroll/10.0.0/js/smooth-scroll.min.js"></script>
<script src="app/js/main.min.js"></script>
</body>
</html>
================================================
FILE: readme.md
================================================
# Boilerform
<img src="https://s3-us-west-2.amazonaws.com/s.cdpn.io/174183/share.png" style="max-width: 100%" alt="The Boilerform logo" />
Boilerform is a little HTML and CSS boilerplate to take the pain away from working with forms.
By providing baseline BEM structured CSS and appropriate attributes on elements: Boilerform gives you a head start building forms in the best possible way with a view to being dropped into most projects.
The idea was first thought-up by [@chriscoyier](https://twitter.com/chriscoyier) on [CSS Tricks](https://css-tricks.com/boilerform).
🌍 <https://boilerform.hankchizljaw.com>
## Getting started
Boilerform is designed to be straight-forward to implement. In its most basic form, you can drop a CSS file into your head with the following snippet:
```html
<link rel="stylesheet" media="all" href="https://cdn.jsdelivr.net/gh/hankchizljaw/boilerform@master/dist/css/boilerform.min.css?v=1.1.1" />
```
Then all you need to do is wrap your elements in a `.boilerform` wrapper. It could be something like this:
```html
<div class="boilerform">
<!-- Add all of your boilerform elements in here 👍 -->
</div>
```
You can also take compiled CSS and HTML from the [dist directory](https://github.com/hankchizljaw/boilerform/tree/master/dist/) of this repository, if that's what you prefer.
If you want a bit more control, you can work with the [Sass](https://github.com/hankchizljaw/boilerform/tree/master/assets/scss) and [Pattern Library](https://github.com/hankchizljaw/boilerform/tree/master/pattern-library). This is where the source of Boilerform lives.
To compile assets, you can run the following commands in your terminal:
- `npm run watch` will compile your assets and watch for further changes
- `npm run build` will compile your assets into a production ready state in the `dist` directory
The pattern library is powered by [Astrum](http://astrum.nodividestudio.com/). You can find [detailed documentation here](https://github.com/NoDivide/Astrum).
## Validation interface
There's a basic validation interface available with Boilerform which extends the native HTML validation facility with a few visual tweaks.
### Getting started
First of all, you need the JavaScript in your project. You can either take the [source code](https://github.com/hankchizljaw/boilerform/blob/master/assets/js/modules/validation.js) and add to your project, or add the dist version to bottom of your page.
```html
<script src="https://cdn.jsdelivr.net/gh/hankchizljaw/boilerform@master/dist/js/boilerform.min.js?v=1.1.1" async defer></script>
```
Now that you've got the script, it'll work, as long as your elements have the `required` attribute, which will allow them to fire an `invalid` event. You'll also need to make sure your `<form>` elements either live in a `.boilerform` parent element or have the `.boilerform` class.
---
Made with ❤️ by [HankChizlJaw](https://twitter.com/hankchizljaw) and [friends](https://github.com/hankchizljaw/boilerform/graphs/contributors).
================================================
FILE: webpack.config.js
================================================
// Pull in .env settings
require('dotenv').config();
// Create CSS and JS output paths
var CSS_OUTPUT_PATH = process.env.CSS_OUTPUT_PATH ? process.env.CSS_OUTPUT_PATH : '../css/boilerform.css';
var JS_OUTPUT_PATH = process.env.JS_OUTPUT_PATH ? process.env.JS_OUTPUT_PATH : '/dist/js';
// Define webpack stuff
var ExtractTextPlugin = require('extract-text-webpack-plugin');
var isProduction = process.env.NODE_ENV === 'production';
var path = require('path');
var plugins = [];
var settings = {
libraryName: 'boilerform',
inputs: {
js: {
entryPath: '/assets/js/boilerform.js'
}
},
outputs: {
js: {
fileName: 'boilerform.js',
minFileName: 'boilerform.min.js',
path: JS_OUTPUT_PATH
},
css: {
path: CSS_OUTPUT_PATH
}
}
};
var webpack = require('webpack');
if(isProduction) {
plugins.push(new webpack.optimize.UglifyJsPlugin({ minimize: true }));
}
// Create an extract text plugin instance for Sass
var extractPlugin = new ExtractTextPlugin(settings.outputs.css.path);
plugins.push(extractPlugin);
module.exports = {
entry: path.join(__dirname, settings.inputs.js.entryPath),
devtool: 'source-map',
output: {
path: path.join(__dirname, settings.outputs.js.path),
filename: (isProduction ? settings.outputs.js.minFileName : settings.outputs.js.fileName),
library: settings.libraryName,
libraryTarget: 'umd',
umdNamedDefine: true
},
module: {
rules: [
{
test: /\.js$/,
exclude: /node_modules/,
use: [
{
loader: 'babel-loader'
}
]
},
{
test: /\.scss$/,
use: extractPlugin.extract({
use: ['css-loader', 'sass-loader']
})
}
]
},
resolve: {
extensions: ['.js']
},
plugins: plugins
};
gitextract_xrdk3epu/ ├── .babelrc ├── .eslintrc ├── .github/ │ ├── ISSUE_TEMPLATE.md │ └── PULL_REQUEST_TEMPLATE.md ├── .gitignore ├── CONTRIBUTING.md ├── LICENSE.txt ├── assets/ │ ├── js/ │ │ ├── boilerform.js │ │ └── modules/ │ │ └── validation.js │ └── scss/ │ ├── _config.scss │ ├── _functions.scss │ ├── _helpers.scss │ ├── _reset.scss │ ├── boilerform.scss │ ├── components/ │ │ ├── _c-button.scss │ │ ├── _c-check-field.scss │ │ ├── _c-input-field.scss │ │ ├── _c-label.scss │ │ └── _c-select-field.scss │ ├── layouts/ │ │ └── _l-form.scss │ └── mixins/ │ └── _namespace.scss ├── astrum-config.json ├── dist/ │ ├── css/ │ │ └── boilerform.css │ ├── js/ │ │ └── boilerform.js │ └── markup/ │ ├── button/ │ │ └── default/ │ │ └── markup.html │ ├── check-field/ │ │ ├── checkbox/ │ │ │ └── markup.html │ │ ├── error-state/ │ │ │ └── markup.html │ │ └── radio/ │ │ └── markup.html │ ├── input-field/ │ │ ├── email/ │ │ │ └── markup.html │ │ ├── error-state/ │ │ │ └── markup.html │ │ ├── number/ │ │ │ └── markup.html │ │ ├── search/ │ │ │ └── markup.html │ │ ├── tel/ │ │ │ └── markup.html │ │ ├── text/ │ │ │ └── markup.html │ │ └── text-area/ │ │ └── markup.html │ ├── label/ │ │ └── default/ │ │ └── markup.html │ └── select-field/ │ ├── error-state/ │ │ └── markup.html │ └── select-menu/ │ └── markup.html ├── generator/ │ └── dist.js ├── package.json ├── pattern-library/ │ ├── LICENSE.txt │ ├── app/ │ │ ├── css/ │ │ │ └── styles.css │ │ └── js/ │ │ └── main.js │ ├── assets/ │ │ └── js/ │ │ └── patterns.js │ ├── components/ │ │ ├── button/ │ │ │ ├── default/ │ │ │ │ ├── description.md │ │ │ │ └── markup.html │ │ │ └── description.md │ │ ├── check-field/ │ │ │ ├── checkbox/ │ │ │ │ ├── description.md │ │ │ │ └── markup.html │ │ │ ├── description.md │ │ │ ├── error-state/ │ │ │ │ ├── description.md │ │ │ │ └── markup.html │ │ │ └── radio/ │ │ │ ├── description.md │ │ │ └── markup.html │ │ ├── input-field/ │ │ │ ├── description.md │ │ │ ├── email/ │ │ │ │ ├── description.md │ │ │ │ └── markup.html │ │ │ ├── error-state/ │ │ │ │ ├── description.md │ │ │ │ └── markup.html │ │ │ ├── number/ │ │ │ │ ├── description.md │ │ │ │ └── markup.html │ │ │ ├── search/ │ │ │ │ ├── description.md │ │ │ │ └── markup.html │ │ │ ├── tel/ │ │ │ │ ├── description.md │ │ │ │ └── markup.html │ │ │ ├── text/ │ │ │ │ ├── description.md │ │ │ │ └── markup.html │ │ │ └── text-area/ │ │ │ ├── description.md │ │ │ └── markup.html │ │ ├── label/ │ │ │ ├── default/ │ │ │ │ ├── description.md │ │ │ │ └── markup.html │ │ │ └── description.md │ │ └── select-field/ │ │ ├── description.md │ │ ├── error-state/ │ │ │ ├── description.md │ │ │ └── markup.html │ │ └── select-menu/ │ │ ├── description.md │ │ └── markup.html │ ├── data.json │ └── index.html ├── readme.md └── webpack.config.js
SYMBOL INDEX (14 symbols across 2 files)
FILE: assets/js/modules/validation.js
class Validation (line 1) | class Validation {
method constructor (line 7) | constructor(baseForm) {
method init (line 17) | init() {
method bind (line 26) | bind() {
method process (line 43) | process(item, state = 'invalid') {
method checkSiblings (line 60) | checkSiblings(exludedField) {
method processValidity (line 72) | processValidity(item) {
FILE: dist/js/boilerform.js
function __webpack_require__ (line 16) | function __webpack_require__(moduleId) {
function _interopRequireDefault (line 91) | function _interopRequireDefault(obj) { return obj && obj.__esModule ? ob...
function _toConsumableArray (line 93) | function _toConsumableArray(arr) { if (Array.isArray(arr)) { for (var i ...
function defineProperties (line 125) | function defineProperties(target, props) { for (var i = 0; i < props.len...
function _toConsumableArray (line 127) | function _toConsumableArray(arr) { if (Array.isArray(arr)) { for (var i ...
function _classCallCheck (line 129) | function _classCallCheck(instance, Constructor) { if (!(instance instanc...
function Validation (line 137) | function Validation(baseForm) {
Condensed preview — 81 files, each showing path, character count, and a content snippet. Download the .json file or copy for the full structured content (133K chars).
[
{
"path": ".babelrc",
"chars": 78,
"preview": "{\n \"presets\": [\"env\"],\n \"plugins\": [\"babel-plugin-add-module-exports\"]\n}"
},
{
"path": ".eslintrc",
"chars": 447,
"preview": "{\n \"parser\": \"babel-eslint\",\n \"env\": {\n \"browser\": true,\n \"commonjs\": true,\n \"es6\": true,\n "
},
{
"path": ".github/ISSUE_TEMPLATE.md",
"chars": 161,
"preview": "## Expected Behavior\n\n\n## Actual Behavior\n\n\n## Steps to Reproduce the Problem\n\n1.\n1.\n1.\n\n## Specifications\n\n- Version:\n-"
},
{
"path": ".github/PULL_REQUEST_TEMPLATE.md",
"chars": 176,
"preview": "Fixes Issue # (Delete if not applicable)\n\n## Proposed Changes\n\n-\n-\n-\n\n## Add a GIF that demonstrates how this Pull Reque"
},
{
"path": ".gitignore",
"chars": 203,
"preview": "# Common\nnode_modules\n.DS_Store\n.sass-cache\n*.log\n*.scssc\nnpm-debug.*\n.env\n\n# Compiled assets\npattern-library/assets/css"
},
{
"path": "CONTRIBUTING.md",
"chars": 3803,
"preview": "# Contributing\n\nWhen contributing to this repository, please first discuss the change you wish to make via issue,\nemail,"
},
{
"path": "LICENSE.txt",
"chars": 1095,
"preview": "MIT License\n\nCopyright (c) 2018 hankchizljaw.io and other contributors\n\nPermission is hereby granted, free of charge, to"
},
{
"path": "assets/js/boilerform.js",
"chars": 517,
"preview": "import Validation from './modules/validation';\n\n// Import Sass so that webpack picks it up\nrequire('../scss/boilerform.s"
},
{
"path": "assets/js/modules/validation.js",
"chars": 1978,
"preview": "export default class Validation {\n\n /**\n * Load up an instance of Validation\n * @param {HTMLFormElement} base"
},
{
"path": "assets/scss/_config.scss",
"chars": 939,
"preview": "// Colors\n$colors: (\n base: (\n text: #141414,\n border: #cccccc \n ),\n button: (\n background"
},
{
"path": "assets/scss/_functions.scss",
"chars": 380,
"preview": "/*------------------------------------*\\\n COLOR\n\n Pass in a group name and a key\n to get a value. \n\n E.G col"
},
{
"path": "assets/scss/_helpers.scss",
"chars": 595,
"preview": "// All input fields share these styles. Also includes select menus\n%c-field-shared-inputs {\n background: color(field,"
},
{
"path": "assets/scss/_reset.scss",
"chars": 1097,
"preview": "@include namespace(true) {\n \n // Set base pixel size for REM units to work off\n font-size: $base-font-size;\n "
},
{
"path": "assets/scss/boilerform.scss",
"chars": 838,
"preview": "// Pull config \n@import \"config\";\n\n// Mixins\n@import \"mixins/namespace\";\n\n// Functions\n@import \"functions\";\n\n// Helpers\n"
},
{
"path": "assets/scss/components/_c-button.scss",
"chars": 791,
"preview": "/*------------------------------------*\\\n BUTTON COMPONENT\n\n Base button styles and reset\n\\*----------------------"
},
{
"path": "assets/scss/components/_c-check-field.scss",
"chars": 1919,
"preview": "/*------------------------------------*\\\n CHECK FIELD COMPONENT\n\n Radio buttons and checkboxes\n\\*-----------------"
},
{
"path": "assets/scss/components/_c-input-field.scss",
"chars": 687,
"preview": "/*------------------------------------*\\\n INPUT FIELD COMPONENT\n\n All input based form field elements\n\\*----------"
},
{
"path": "assets/scss/components/_c-label.scss",
"chars": 686,
"preview": "/*------------------------------------*\\\n LABEL COMPONENT\n\n A simple form label\n\\*--------------------------------"
},
{
"path": "assets/scss/components/_c-select-field.scss",
"chars": 980,
"preview": "/*------------------------------------*\\\n SELECT FIELD\n\n Option driven fields such as \n <select> menus\n\\*------"
},
{
"path": "assets/scss/layouts/_l-form.scss",
"chars": 247,
"preview": "/*------------------------------------*\\\n FORM LAYOUT\n\n The main form layout that gives\n you rythm, alignment a"
},
{
"path": "assets/scss/mixins/_namespace.scss",
"chars": 406,
"preview": "/*------------------------------------*\\\n NAMESPACE\n\n This mixin encapsulates CSS within \n a namespace to preve"
},
{
"path": "astrum-config.json",
"chars": 33,
"preview": "{\n \"path\": \"pattern-library\"\n}"
},
{
"path": "dist/css/boilerform.css",
"chars": 5532,
"preview": "/*------------------------------------* NAMESPACE\n\n This mixin encapsulates CSS within \n a namespace to prevent"
},
{
"path": "dist/js/boilerform.js",
"chars": 9950,
"preview": "(function webpackUniversalModuleDefinition(root, factory) {\n\tif(typeof exports === 'object' && typeof module === 'object"
},
{
"path": "dist/markup/button/default/markup.html",
"chars": 42,
"preview": "<button class=\"c-button\">A button</button>"
},
{
"path": "dist/markup/check-field/checkbox/markup.html",
"chars": 330,
"preview": "<div class=\"c-check-field\">\n <input type=\"checkbox\" name=\"checkbox-field\" id=\"checkbox-field\" class=\"c-check-field__i"
},
{
"path": "dist/markup/check-field/error-state/markup.html",
"chars": 748,
"preview": "<div class=\"[ c-check-field ] [ is-error ]\">\n <input type=\"checkbox\" name=\"checkbox-error-field\" id=\"checkbox-error-f"
},
{
"path": "dist/markup/check-field/radio/markup.html",
"chars": 747,
"preview": "<div class=\"c-check-field c-check-field--radio\">\n <input type=\"radio\" name=\"checkbox-field\" id=\"checkbox-radio-field-"
},
{
"path": "dist/markup/input-field/email/markup.html",
"chars": 121,
"preview": "<input type=\"email\" name=\"\" id=\"\" autocapitalize=\"none\" autocorrect=\"off\" class=\"c-input-field\" value=\"user@email.com\" /"
},
{
"path": "dist/markup/input-field/error-state/markup.html",
"chars": 95,
"preview": "<input type=\"text\" name=\"\" id=\"\" class=\"[ c-input-field ] [ is-error ]\" value=\"Generic text\" />"
},
{
"path": "dist/markup/input-field/number/markup.html",
"chars": 98,
"preview": "<input type=\"number\" name=\"\" id=\"\" min=\"1\" max=\"999\" step=\"1\" class=\"c-input-field\" value=\"123\" />"
},
{
"path": "dist/markup/input-field/search/markup.html",
"chars": 103,
"preview": "<input type=\"search\" name=\"\" id=\"\" autocorrect=\"off\" class=\"c-input-field\" value=\"Some search terms\" />"
},
{
"path": "dist/markup/input-field/tel/markup.html",
"chars": 78,
"preview": "<input type=\"tel\" name=\"\" id=\"\" class=\"c-input-field\" value=\"01234 567 890\" />"
},
{
"path": "dist/markup/input-field/text/markup.html",
"chars": 78,
"preview": "<input type=\"text\" name=\"\" id=\"\" class=\"c-input-field\" value=\"Generic text\" />"
},
{
"path": "dist/markup/input-field/text-area/markup.html",
"chars": 101,
"preview": "<textarea name=\"\" id=\"\" class=\"c-input-field c-input-field--multiline\">Some multiline text</textarea>"
},
{
"path": "dist/markup/label/default/markup.html",
"chars": 104,
"preview": "<label for=\"\" class=\"c-label\">A label for a field</label>\n<input class=\"c-input-field\" value=\"fdsfds\" />"
},
{
"path": "dist/markup/select-field/error-state/markup.html",
"chars": 424,
"preview": "<div class=\"[ c-select-field ] [ is-error ]\">\n <select name=\"\" id=\"\" class=\"c-select-field__menu\">\n <option>Se"
},
{
"path": "dist/markup/select-field/select-menu/markup.html",
"chars": 407,
"preview": "<div class=\"c-select-field\">\n <select name=\"\" id=\"\" class=\"c-select-field__menu\">\n <option>Select an item</opt"
},
{
"path": "generator/dist.js",
"chars": 607,
"preview": "var findRemoveSync = require('find-remove');\nvar fs = require('fs');\nvar ncp = require('ncp');\nvar path = require('path"
},
{
"path": "package.json",
"chars": 1160,
"preview": "{\n \"name\": \"boilerform\",\n \"version\": \"1.1.1\",\n \"description\": \"A little collection of common form elements that have "
},
{
"path": "pattern-library/LICENSE.txt",
"chars": 1096,
"preview": "Copyright (c) Astrum by No Divide Studio Ltd (http://nodividestudio.com)\n\nPermission is hereby granted, free of charge, "
},
{
"path": "pattern-library/app/css/styles.css",
"chars": 24084,
"preview": "/**\n * Base styles\n * ----------------------------------------//\n */\n.ndpl-body {\n background-color: #FFF;\n -ms-ov"
},
{
"path": "pattern-library/app/js/main.js",
"chars": 26763,
"preview": "/**\n * Component component\n */\nvar ndplComponent = Vue.extend({\n\n data: function() {\n return {\n loa"
},
{
"path": "pattern-library/assets/js/patterns.js",
"chars": 260,
"preview": "(function() {\n var componentSamples = [].slice.call(document.querySelectorAll('.ndpl-component__sample'));\n\n if(co"
},
{
"path": "pattern-library/components/button/default/description.md",
"chars": 0,
"preview": ""
},
{
"path": "pattern-library/components/button/default/markup.html",
"chars": 42,
"preview": "<button class=\"c-button\">A button</button>"
},
{
"path": "pattern-library/components/button/description.md",
"chars": 0,
"preview": ""
},
{
"path": "pattern-library/components/check-field/checkbox/description.md",
"chars": 0,
"preview": ""
},
{
"path": "pattern-library/components/check-field/checkbox/markup.html",
"chars": 330,
"preview": "<div class=\"c-check-field\">\n <input type=\"checkbox\" name=\"checkbox-field\" id=\"checkbox-field\" class=\"c-check-field__i"
},
{
"path": "pattern-library/components/check-field/description.md",
"chars": 0,
"preview": ""
},
{
"path": "pattern-library/components/check-field/error-state/description.md",
"chars": 0,
"preview": ""
},
{
"path": "pattern-library/components/check-field/error-state/markup.html",
"chars": 748,
"preview": "<div class=\"[ c-check-field ] [ is-error ]\">\n <input type=\"checkbox\" name=\"checkbox-error-field\" id=\"checkbox-error-f"
},
{
"path": "pattern-library/components/check-field/radio/description.md",
"chars": 0,
"preview": ""
},
{
"path": "pattern-library/components/check-field/radio/markup.html",
"chars": 747,
"preview": "<div class=\"c-check-field c-check-field--radio\">\n <input type=\"radio\" name=\"checkbox-field\" id=\"checkbox-radio-field-"
},
{
"path": "pattern-library/components/input-field/description.md",
"chars": 165,
"preview": "Generic input fields with variations for size, placeholders and validation states. Relevant attributes are added to help"
},
{
"path": "pattern-library/components/input-field/email/description.md",
"chars": 0,
"preview": ""
},
{
"path": "pattern-library/components/input-field/email/markup.html",
"chars": 121,
"preview": "<input type=\"email\" name=\"\" id=\"\" autocapitalize=\"none\" autocorrect=\"off\" class=\"c-input-field\" value=\"user@email.com\" /"
},
{
"path": "pattern-library/components/input-field/error-state/description.md",
"chars": 0,
"preview": ""
},
{
"path": "pattern-library/components/input-field/error-state/markup.html",
"chars": 95,
"preview": "<input type=\"text\" name=\"\" id=\"\" class=\"[ c-input-field ] [ is-error ]\" value=\"Generic text\" />"
},
{
"path": "pattern-library/components/input-field/number/description.md",
"chars": 0,
"preview": ""
},
{
"path": "pattern-library/components/input-field/number/markup.html",
"chars": 98,
"preview": "<input type=\"number\" name=\"\" id=\"\" min=\"1\" max=\"999\" step=\"1\" class=\"c-input-field\" value=\"123\" />"
},
{
"path": "pattern-library/components/input-field/search/description.md",
"chars": 0,
"preview": ""
},
{
"path": "pattern-library/components/input-field/search/markup.html",
"chars": 103,
"preview": "<input type=\"search\" name=\"\" id=\"\" autocorrect=\"off\" class=\"c-input-field\" value=\"Some search terms\" />"
},
{
"path": "pattern-library/components/input-field/tel/description.md",
"chars": 0,
"preview": ""
},
{
"path": "pattern-library/components/input-field/tel/markup.html",
"chars": 78,
"preview": "<input type=\"tel\" name=\"\" id=\"\" class=\"c-input-field\" value=\"01234 567 890\" />"
},
{
"path": "pattern-library/components/input-field/text/description.md",
"chars": 0,
"preview": ""
},
{
"path": "pattern-library/components/input-field/text/markup.html",
"chars": 78,
"preview": "<input type=\"text\" name=\"\" id=\"\" class=\"c-input-field\" value=\"Generic text\" />"
},
{
"path": "pattern-library/components/input-field/text-area/description.md",
"chars": 0,
"preview": ""
},
{
"path": "pattern-library/components/input-field/text-area/markup.html",
"chars": 101,
"preview": "<textarea name=\"\" id=\"\" class=\"c-input-field c-input-field--multiline\">Some multiline text</textarea>"
},
{
"path": "pattern-library/components/label/default/description.md",
"chars": 0,
"preview": ""
},
{
"path": "pattern-library/components/label/default/markup.html",
"chars": 104,
"preview": "<label for=\"\" class=\"c-label\">A label for a field</label>\n<input class=\"c-input-field\" value=\"fdsfds\" />"
},
{
"path": "pattern-library/components/label/description.md",
"chars": 0,
"preview": ""
},
{
"path": "pattern-library/components/select-field/description.md",
"chars": 0,
"preview": ""
},
{
"path": "pattern-library/components/select-field/error-state/description.md",
"chars": 0,
"preview": ""
},
{
"path": "pattern-library/components/select-field/error-state/markup.html",
"chars": 424,
"preview": "<div class=\"[ c-select-field ] [ is-error ]\">\n <select name=\"\" id=\"\" class=\"c-select-field__menu\">\n <option>Se"
},
{
"path": "pattern-library/components/select-field/select-menu/description.md",
"chars": 0,
"preview": ""
},
{
"path": "pattern-library/components/select-field/select-menu/markup.html",
"chars": 407,
"preview": "<div class=\"c-select-field\">\n <select name=\"\" id=\"\" class=\"c-select-field__menu\">\n <option>Select an item</opt"
},
{
"path": "pattern-library/data.json",
"chars": 4968,
"preview": "{\n \"project_logo\": \"/assets/images/logo/logo.svg\",\n \"project_favicon\": \"favicon.png\",\n \"project_name\": \"Boilerf"
},
{
"path": "pattern-library/index.html",
"chars": 16478,
"preview": "<!DOCTYPE html>\n<html lang=\"en\" class=\"ndpl-c-background\">\n <head>\n <meta charset=\"UTF-8\">\n <meta name="
},
{
"path": "readme.md",
"chars": 3019,
"preview": "# Boilerform\n\n<img src=\"https://s3-us-west-2.amazonaws.com/s.cdpn.io/174183/share.png\" style=\"max-width: 100%\" alt=\"The "
},
{
"path": "webpack.config.js",
"chars": 2059,
"preview": "// Pull in .env settings \nrequire('dotenv').config();\n\n// Create CSS and JS output paths \nvar CSS_OUTPUT_PATH = process."
}
]
About this extraction
This page contains the full source code of the hankchizljaw/boilerform GitHub repository, extracted and formatted as plain text for AI agents and large language models (LLMs). The extraction includes 81 files (118.3 KB), approximately 31.4k tokens, and a symbol index with 14 extracted functions, classes, methods, constants, and types. Use this with OpenClaw, Claude, ChatGPT, Cursor, Windsurf, or any other AI tool that accepts text input. You can copy the full output to your clipboard or download it as a .txt file.
Extracted by GitExtract — free GitHub repo to text converter for AI. Built by Nikandr Surkov.