diff --git a/dist/index.html b/dist/index.html
index b873b1e..c75e534 100644
--- a/dist/index.html
+++ b/dist/index.html
@@ -4,17 +4,168 @@
My JavaScript App
+
+
+
+
-
-
+
+
+
+
+
+
+
+
+ Trips
+
+
+
+
+
+
+
+
+
+ | Name |
+ Continent |
+ Category |
+ Weeks |
+ Cost |
+
+
+
+
+
+
+
+
+
+
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Don't Add
+
-
+
+
+
+
+
diff --git a/package-lock.json b/package-lock.json
index f830985..74b17bc 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -5017,6 +5017,11 @@
"resolved": "https://registry.npmjs.org/jquery/-/jquery-3.2.1.tgz",
"integrity": "sha1-XE2d5lKvbNCncBVKYxu6ErAVx4c="
},
+ "jquery-modal": {
+ "version": "0.9.1",
+ "resolved": "https://registry.npmjs.org/jquery-modal/-/jquery-modal-0.9.1.tgz",
+ "integrity": "sha512-04C0nhhFBDkFt3VUQaZDOXWPifpJHm8JjhgydePV1drI9ZvOTkIRLVOzCy2mo5/bcWqPU8UhLq4L6Pdex//lvw=="
+ },
"js-base64": {
"version": "2.3.2",
"resolved": "https://registry.npmjs.org/js-base64/-/js-base64-2.3.2.tgz",
diff --git a/package.json b/package.json
index 5860ddc..9035c63 100644
--- a/package.json
+++ b/package.json
@@ -58,6 +58,7 @@
"dependencies": {
"backbone": "^1.3.3",
"jquery": "^3.2.1",
+ "jquery-modal": "^0.9.1",
"underscore": "^1.8.3"
}
}
diff --git a/src/app.js b/src/app.js
index e7af594..8cafaa3 100644
--- a/src/app.js
+++ b/src/app.js
@@ -1,13 +1,277 @@
// Vendor Modules
import $ from 'jquery';
import _ from 'underscore';
+import 'jquery-modal';
// CSS
import './css/foundation.css';
+import './css/responsive-tables.css';
import './css/style.css';
-console.log('it loaded!');
+import './responsive-tables';
+
+import Trip from './app/models/trip';
+import TripList from './app/collections/trip_list';
+import Reservation from './app/models/reservation';
+
+const allTrips = new TripList();
+let filteredTrips = allTrips;
+
+let tripListTemplate;
+let tripTemplate;
+
+// renders
+const renderTripList = function renderTripList(tripList) {
+ // empty existing list and res form
+ const $tripList = $('#trip-list');
+ $tripList.empty();
+ $('#reservation').empty();
+
+ tripList.forEach((trip) => {
+ $tripList.append(tripListTemplate(trip.attributes));
+ });
+};
+
+const renderTrip = function renderTrip(trip) {
+ const $tripDetail = $('#trip-detail');
+
+ $tripDetail.empty();
+ $tripDetail.append(tripTemplate(trip.attributes))
+ $('.reservation').append(loadResForm(trip.id));
+};
+
+const cancelSubmit = function cancelSubmit() {
+ const $form = $(this).parent();
+ $form.trigger('reset');
+ $form.find('p').remove();
+ $form.find('input').removeClass('error');
+ // $(this).parent().trigger('reset');
+ // $(this).parent().find('p').remove();
+ // $('.error-messages').empty();
+};
+
+const readForm = function readForm(form) {
+ const fields = form.find(':input').not('button');
+ const formData = {};
+
+ for (let i = 0; i < fields.length; i += 1) {
+ const field = fields[i];
+ formData[field.name] = $(`#${field.id}`).val();
+ }
+
+ return formData;
+};
+
+const readTripForm = function readTripForm() {
+ const $tripForm = $('#add-trip-form');
+ return readForm($tripForm);
+};
+
+const readResForm = function readResForm() {
+ const $resForm = $('#add-res-form');
+ const tripId = $resForm.data('id');
+ const resData = readForm($resForm);
+
+ resData['trip_id'] = tripId;
+
+ return resData
+}
+
+const renderSuccess = function renderSuccess(message, section) {
+ // const $msgSection = $('main > .status-messages')
+
+ section.addClass('success');
+ section.append(`${message}
`);
+ // $msgSection.delay(5000).fadeout();
+}
+
+const renderError = function renderError(field, error, form) {
+ const html = `${error}
`;
+ const $errorInput = form.find(`input[name=${field}]`);
+
+ $errorInput.before(html);
+ $errorInput.addClass('error');
+};
+
+const handleValidationErrors = function handleValidationErrors(errors, form) {
+ Object.keys(errors).forEach((field) => {
+ errors[field].forEach((error) => {
+ renderError(field, error, form);
+ });
+ });
+};
+
+const getTrip = function getTrip(event) {
+ const tripId = event.currentTarget.id;
+ let trip = new Trip({id: tripId});
+
+ trip.fetch({
+ success: function(trip, response, options) {
+
+ // render error if no content
+ if (options.xhr.status === 204) {
+ const html = 'Trip Not Found
';
+ $('.detail.status-messages').append(html);
+ } else {
+ renderTrip(trip);
+ }
+ },
+ // how is this handled???
+ error: function(trip) {
+ console.log(trip);
+ }
+ });
+};
+
+// const successfulSave = function successfulSave(trip) {
+// $('.error-messages').empty();
+//
+// tripList.add(trip);
+// $.modal.close();
+// };
+
+const addTrip = function addTrip(event) {
+ event.preventDefault();
+ const trip = new Trip(readTripForm());
+
+ // client side validations
+ if (trip.isValid()) {
+ trip.save({}, {
+ success: () => {
+ if ($('#add-trip-form p').length) {
+ $('#add-trip-form p').remove();
+ }
+
+ allTrips.add(trip);
+ $.modal.close();
+
+ renderSuccess('Trip successfully added', $('main > .status-messages'));
+ },
+ // success: successfulSave,
+ error: (model, response) => {
+ handleValidationErrors(response.responseJSON.errors, $('#add-trip-form'));
+ }
+ // error: failedSave
+ });
+ } else {
+ handleValidationErrors(trip.validationError, $('#add-trip-form'));
+ }
+};
+
+const loadResForm = function loadTripForm(tripId) {
+ const html = `
+ `;
+
+ $('.reservation').append(html);
+};
+
+const addRes = function addRes(event) {
+ event.preventDefault();
+
+ const res = new Reservation(readResForm());
+
+ // client-side validations
+ if (res.isValid()) {
+ res.save({}, {
+ success: () => {
+ // if ($('#add-res-form p').length) {
+ $('#add-res-form p').remove();
+ // }
+ renderSuccess('Spot reserved', $('#add-res-form .status-messages'));
+ $('#add-res-form').trigger('reset');
+ },
+ error: (model, response) => {
+ handleValidationErrors(response.responseJSON.errors, $('#add-res-form'));
+ }
+ });
+ }
+ else {
+ handleValidationErrors(res.validationError, $('#add-res-form'));
+ }
+};
+
+const sortTrips = function sortTrips() {
+ const fields = ['id', 'name', 'continent', 'category', 'cost', 'weeks'];
+
+ $('.current-sort-field').removeClass('current-sort-field');
+ $(this).addClass('current-sort-field');
+
+ const classes = $(this).attr('class').split(/\s+/);
+
+ classes.forEach((className) => {
+ // if already sorted, sort desc
+ if (fields.includes(className)) {
+ if (className === allTrips.comparator) {
+ allTrips.models.reverse();
+ allTrips.trigger('sort', allTrips);
+ // sort asc
+ } else {
+ allTrips.comparator = className;
+ allTrips.sort();
+ }
+ }
+ });
+};
+
+const filterTrips = function filterTrips() {
+ const $filter = $('#filter-by option:checked').val();
+ // make empty string if undefined
+ const $search = $('#search').val() || "";
+ filteredTrips = allTrips.filterBy($filter, $search);
+ renderTripList(filteredTrips);
+};
+
+const init = () => {
+ $('body').removeClass('init');
+ $('div.init').hide();
+ $('header').addClass('grid-x');
+ $('header').show();
+ $('main').addClass('grid-x grid-padding-x')
+ $('main').show();
+
+ allTrips.fetch();
+};
$(document).ready( () => {
- $('main').html('Hello World!
');
+ // load templates
+ tripListTemplate = _.template($('#trip-list-template').html());
+ tripTemplate = _.template($('#trip-template').html());
+
+ $('.start').on('click', init);
+
+ allTrips.on('update', renderTripList, allTrips);
+ allTrips.on('sort', renderTripList, allTrips);
+ // filteredTrips.on('update', renderTripList, filteredTrips);
+
+ $('#trip-list').on('mouseover', 'tr', getTrip, this);
+ $('.all-trips th').on('click', sortTrips);
+
+ $('.cancel').on('click', cancelSubmit);
+ $('#add-trip-form').on('submit', addTrip);
+
+ $('#trip-detail').on('submit', '#add-res-form', addRes);
+ $('#filter').on('change keyup', 'input, select', filterTrips);
+ // $('#filter').on('change', 'select', filterTrips);
+
+ // allTrips.fetch();
});
diff --git a/src/app/collections/trip_list.js b/src/app/collections/trip_list.js
new file mode 100644
index 0000000..0e3d799
--- /dev/null
+++ b/src/app/collections/trip_list.js
@@ -0,0 +1,44 @@
+import Backbone from 'backbone';
+import Trip from '../models/trip';
+
+const TripList = Backbone.Collection.extend({
+ model: Trip,
+ url: 'https://ada-backtrek-api.herokuapp.com/trips',
+ comparator: 'id',
+ greaterThan(field, value) {
+ let models = this.select(function(model) {
+ return model.get(`${field}`) > value;
+ });
+ return new TripList(models);
+ },
+ includes(field, value) {
+ if (field === undefined || field === '') {
+ let models = this.select(function(model) {
+ const attributes = Object.keys(model.attributes);
+
+ for (let i = 0; i < attributes.length; i += 1) {
+ if (typeof model.get(attributes[i]) === 'number') {
+ if (model.get(attributes[i]).toString().includes(value)) return true;
+ // return model.get(attributes[i]).toString().includes(value);
+ } else {
+ if (model.get(attributes[i]).toLowerCase().includes(value.toLowerCase())) return true;
+ }
+ }
+ return false;
+ });
+ return new TripList(models);
+ } else {
+ let models = this.select(function(model) {
+ return model.get(`${field}`).toLowerCase().includes(value.toLowerCase());
+ });
+ return new TripList(models);
+ }
+ },
+ filterBy(field, value) {
+ if (field === 'cost' || field === 'weeks') return this.greaterThan(field, value);
+
+ return this.includes(field, value);
+ }
+});
+
+export default TripList;
diff --git a/src/app/models/reservation.js b/src/app/models/reservation.js
new file mode 100644
index 0000000..15473e7
--- /dev/null
+++ b/src/app/models/reservation.js
@@ -0,0 +1,28 @@
+import Backbone from 'backbone';
+
+const Reservation = Backbone.Model.extend({
+ urlRoot: '/trips',
+
+ initialize(attributes) {
+ this.url = 'https://ada-backtrek-api.herokuapp.com/trips/' + attributes.trip_id + '/reservations';
+ },
+
+ validate(attributes) {
+ const errors = {};
+
+ if (!attributes.name) {
+ errors['name'] = ['Cannot be blank'];
+ }
+
+ if (!attributes.email) {
+ errors['email'] = ['Cannot be blank'];
+ }
+
+ if (Object.keys(errors).length > 0) {
+ return errors;
+ }
+ return false;
+ },
+});
+
+export default Reservation;
diff --git a/src/app/models/trip.js b/src/app/models/trip.js
new file mode 100644
index 0000000..d17f54d
--- /dev/null
+++ b/src/app/models/trip.js
@@ -0,0 +1,48 @@
+import Backbone from 'backbone';
+
+const Trip = Backbone.Model.extend({
+ urlRoot: 'https://ada-backtrek-api.herokuapp.com/trips',
+
+ validate(attributes) {
+ const errors = {};
+
+ const continents = ['Africa', 'Antartica', 'Asia', 'Australasia', 'Europe', 'North America', 'South America'];
+
+ if (!attributes.name) {
+ errors['name']= ['Cannot be blank'];
+ }
+
+ if (!attributes.continent) {
+ errors['continent'] = ['Cannot be blank'];
+ } else if (!continents.includes(attributes.continent)) {
+ errors['continent'] =['Is not a continent in the list'];
+ }
+
+ if (!attributes.category) {
+ errors['category'] = ['Cannot be blank'];
+ }
+
+ if (!attributes.weeks) {
+ errors['weeks'] = ['Cannot be blank'];
+ } else if (isNaN(attributes.weeks)) {
+ errors['weeks'] = ['Must be a number'];
+ } else if (attributes.weeks <= 0) {
+ errors['weeks']= ['Must be greater than 0'];
+ }
+
+ if (!attributes.cost) {
+ errors['cost']= ['Cannot be blank'];
+ } else if (isNaN(attributes.cost)) {
+ errors['cost'] = ['Must be a number'];
+ } else if (attributes.weeks <= 0) {
+ errors['cost'] = ['Must be greater than 0'];
+ }
+
+ if (Object.keys(errors).length > 0) {
+ return errors;
+ }
+ return false;
+ },
+});
+
+export default Trip;
diff --git a/src/css/favicon.png b/src/css/favicon.png
new file mode 100644
index 0000000..b823905
Binary files /dev/null and b/src/css/favicon.png differ
diff --git a/src/css/foundation.css b/src/css/foundation.css
index c59eaf5..ac6648c 100644
--- a/src/css/foundation.css
+++ b/src/css/foundation.css
@@ -1,143 +1,188 @@
@charset "UTF-8";
/**
* Foundation for Sites by ZURB
- * Version 6.2.4
+ * Version 6.4.2
* foundation.zurb.com
* Licensed under MIT Open Source
*/
-/*! normalize.css v3.0.3 | MIT License | github.com/necolas/normalize.css */
+@media print, screen and (min-width: 40em) {
+ .reveal, .reveal.tiny, .reveal.small, .reveal.large {
+ right: auto;
+ left: auto;
+ margin: 0 auto; } }
+
+/*! normalize-scss | MIT/GPLv2 License | bit.ly/normalize-scss */
+/* Document
+ ========================================================================== */
/**
- * 1. Set default font family to sans-serif.
- * 2. Prevent iOS and IE text size adjust after device orientation change,
- * without disabling user zoom.
- */
+ * 1. Change the default font family in all browsers (opinionated).
+ * 2. Correct the line height in all browsers.
+ * 3. Prevent adjustments of font size after orientation changes in
+ * IE on Windows Phone and in iOS.
+ */
html {
font-family: sans-serif;
/* 1 */
- -ms-text-size-adjust: 100%;
+ line-height: 1.15;
/* 2 */
+ -ms-text-size-adjust: 100%;
+ /* 3 */
-webkit-text-size-adjust: 100%;
- /* 2 */ }
+ /* 3 */ }
+/* Sections
+ ========================================================================== */
/**
- * Remove default margin.
- */
+ * Remove the margin in all browsers (opinionated).
+ */
body {
margin: 0; }
-/* HTML5 display definitions
- ========================================================================== */
/**
- * Correct `block` display not defined for any HTML5 element in IE 8/9.
- * Correct `block` display not defined for `details` or `summary` in IE 10/11
- * and Firefox.
- * Correct `block` display not defined for `main` in IE 11.
- */
+ * Add the correct display in IE 9-.
+ */
article,
aside,
-details,
-figcaption,
-figure,
footer,
header,
-hgroup,
-main,
-menu,
nav,
-section,
-summary {
+section {
display: block; }
/**
- * 1. Correct `inline-block` display not defined in IE 8/9.
- * 2. Normalize vertical alignment of `progress` in Chrome, Firefox, and Opera.
- */
-audio,
-canvas,
-progress,
-video {
- display: inline-block;
+ * Correct the font size and margin on `h1` elements within `section` and
+ * `article` contexts in Chrome, Firefox, and Safari.
+ */
+h1 {
+ font-size: 2em;
+ margin: 0.67em 0; }
+
+/* Grouping content
+ ========================================================================== */
+/**
+ * Add the correct display in IE 9-.
+ */
+figcaption,
+figure {
+ display: block; }
+
+/**
+ * Add the correct margin in IE 8.
+ */
+figure {
+ margin: 1em 40px; }
+
+/**
+ * 1. Add the correct box sizing in Firefox.
+ * 2. Show the overflow in Edge and IE.
+ */
+hr {
+ box-sizing: content-box;
/* 1 */
- vertical-align: baseline;
+ height: 0;
+ /* 1 */
+ overflow: visible;
/* 2 */ }
/**
- * Prevent modern browsers from displaying `audio` without controls.
- * Remove excess height in iOS 5 devices.
- */
-audio:not([controls]) {
- display: none;
- height: 0; }
+ * Add the correct display in IE.
+ */
+main {
+ display: block; }
/**
- * Address `[hidden]` styling not present in IE 8/9/10.
- * Hide the `template` element in IE 8/9/10/11, Safari, and Firefox < 22.
- */
-[hidden],
-template {
- display: none; }
+ * 1. Correct the inheritance and scaling of font size in all browsers.
+ * 2. Correct the odd `em` font sizing in all browsers.
+ */
+pre {
+ font-family: monospace, monospace;
+ /* 1 */
+ font-size: 1em;
+ /* 2 */ }
/* Links
- ========================================================================== */
+ ========================================================================== */
/**
- * Remove the gray background color from active links in IE 10.
- */
+ * 1. Remove the gray background on active links in IE 10.
+ * 2. Remove gaps in links underline in iOS 8+ and Safari 8+.
+ */
a {
- background-color: transparent; }
+ background-color: transparent;
+ /* 1 */
+ -webkit-text-decoration-skip: objects;
+ /* 2 */ }
/**
- * Improve readability of focused elements when they are also in an
- * active/hover state.
- */
+ * Remove the outline on focused links when they are also active or hovered
+ * in all browsers (opinionated).
+ */
a:active,
a:hover {
- outline: 0; }
+ outline-width: 0; }
/* Text-level semantics
- ========================================================================== */
+ ========================================================================== */
/**
- * Address styling not present in IE 8/9/10/11, Safari, and Chrome.
- */
+ * 1. Remove the bottom border in Firefox 39-.
+ * 2. Add the correct text decoration in Chrome, Edge, IE, Opera, and Safari.
+ */
abbr[title] {
- border-bottom: 1px dotted; }
+ border-bottom: none;
+ /* 1 */
+ text-decoration: underline;
+ /* 2 */
+ text-decoration: underline dotted;
+ /* 2 */ }
/**
- * Address style set to `bolder` in Firefox 4+, Safari, and Chrome.
- */
+ * Prevent the duplicate application of `bolder` by the next rule in Safari 6.
+ */
b,
strong {
- font-weight: bold; }
+ font-weight: inherit; }
/**
- * Address styling not present in Safari and Chrome.
- */
-dfn {
- font-style: italic; }
+ * Add the correct font weight in Chrome, Edge, and Safari.
+ */
+b,
+strong {
+ font-weight: bolder; }
/**
- * Address variable `h1` font-size and margin within `section` and `article`
- * contexts in Firefox 4+, Safari, and Chrome.
- */
-h1 {
- font-size: 2em;
- margin: 0.67em 0; }
+ * 1. Correct the inheritance and scaling of font size in all browsers.
+ * 2. Correct the odd `em` font sizing in all browsers.
+ */
+code,
+kbd,
+samp {
+ font-family: monospace, monospace;
+ /* 1 */
+ font-size: 1em;
+ /* 2 */ }
/**
- * Address styling not present in IE 8/9.
- */
+ * Add the correct font style in Android 4.3-.
+ */
+dfn {
+ font-style: italic; }
+
+/**
+ * Add the correct background and color in IE 9-.
+ */
mark {
- background: #ff0;
+ background-color: #ff0;
color: #000; }
/**
- * Address inconsistent and variable font size in all browsers.
- */
+ * Add the correct font size in all browsers.
+ */
small {
font-size: 80%; }
/**
- * Prevent `sub` and `sup` affecting `line-height` in all browsers.
- */
+ * Prevent `sub` and `sup` elements from affecting the line height in
+ * all browsers.
+ */
sub,
sup {
font-size: 75%;
@@ -145,228 +190,250 @@ sup {
position: relative;
vertical-align: baseline; }
-sup {
- top: -0.5em; }
-
sub {
bottom: -0.25em; }
-/* Embedded content
- ========================================================================== */
-/**
- * Remove border when inside `a` element in IE 8/9/10.
- */
-img {
- border: 0; }
-
-/**
- * Correct overflow not hidden in IE 9/10/11.
- */
-svg:not(:root) {
- overflow: hidden; }
+sup {
+ top: -0.5em; }
-/* Grouping content
- ========================================================================== */
+/* Embedded content
+ ========================================================================== */
/**
- * Address margin not present in IE 8/9 and Safari.
- */
-figure {
- margin: 1em 40px; }
+ * Add the correct display in IE 9-.
+ */
+audio,
+video {
+ display: inline-block; }
/**
- * Address differences between Firefox and other browsers.
- */
-hr {
- box-sizing: content-box;
+ * Add the correct display in iOS 4-7.
+ */
+audio:not([controls]) {
+ display: none;
height: 0; }
/**
- * Contain overflow in all browsers.
- */
-pre {
- overflow: auto; }
+ * Remove the border on images inside links in IE 10-.
+ */
+img {
+ border-style: none; }
/**
- * Address odd `em`-unit font size rendering in all browsers.
- */
-code,
-kbd,
-pre,
-samp {
- font-family: monospace, monospace;
- font-size: 1em; }
+ * Hide the overflow in IE.
+ */
+svg:not(:root) {
+ overflow: hidden; }
/* Forms
- ========================================================================== */
-/**
- * Known limitation: by default, Chrome and Safari on OS X allow very limited
- * styling of `select`, unless a `border` property is set.
- */
+ ========================================================================== */
/**
- * 1. Correct color not being inherited.
- * Known issue: affects color of disabled elements.
- * 2. Correct font properties not being inherited.
- * 3. Address margins set differently in Firefox 4+, Safari, and Chrome.
- */
+ * 1. Change the font styles in all browsers (opinionated).
+ * 2. Remove the margin in Firefox and Safari.
+ */
button,
input,
optgroup,
select,
textarea {
- color: inherit;
+ font-family: sans-serif;
+ /* 1 */
+ font-size: 100%;
+ /* 1 */
+ line-height: 1.15;
/* 1 */
- font: inherit;
- /* 2 */
margin: 0;
- /* 3 */ }
+ /* 2 */ }
/**
- * Address `overflow` set to `hidden` in IE 8/9/10/11.
- */
+ * Show the overflow in IE.
+ */
button {
overflow: visible; }
/**
- * Address inconsistent `text-transform` inheritance for `button` and `select`.
- * All other form control elements do not inherit `text-transform` values.
- * Correct `button` style inheritance in Firefox, IE 8/9/10/11, and Opera.
- * Correct `select` style inheritance in Firefox.
- */
+ * Remove the inheritance of text transform in Edge, Firefox, and IE.
+ * 1. Remove the inheritance of text transform in Firefox.
+ */
button,
select {
+ /* 1 */
text-transform: none; }
/**
- * 1. Avoid the WebKit bug in Android 4.0.* where (2) destroys native `audio`
- * and `video` controls.
- * 2. Correct inability to style clickable `input` types in iOS.
- * 3. Improve usability and consistency of cursor style between image-type
- * `input` and others.
- */
+ * 1. Prevent a WebKit bug where (2) destroys native `audio` and `video`
+ * controls in Android 4.
+ * 2. Correct the inability to style clickable types in iOS and Safari.
+ */
button,
-html input[type="button"],
-input[type="reset"],
-input[type="submit"] {
+html [type="button"],
+[type="reset"],
+[type="submit"] {
-webkit-appearance: button;
- /* 2 */
- cursor: pointer;
- /* 3 */ }
-
-/**
- * Re-set default cursor for disabled elements.
- */
-button[disabled],
-html input[disabled] {
- cursor: not-allowed; }
+ /* 2 */ }
-/**
- * Remove inner padding and border in Firefox 4+.
- */
-button::-moz-focus-inner,
-input::-moz-focus-inner {
- border: 0;
- padding: 0; }
+button,
+[type="button"],
+[type="reset"],
+[type="submit"] {
+ /**
+ * Remove the inner border and padding in Firefox.
+ */
+ /**
+ * Restore the focus styles unset by the previous rule.
+ */ }
+ button::-moz-focus-inner,
+ [type="button"]::-moz-focus-inner,
+ [type="reset"]::-moz-focus-inner,
+ [type="submit"]::-moz-focus-inner {
+ border-style: none;
+ padding: 0; }
+ button:-moz-focusring,
+ [type="button"]:-moz-focusring,
+ [type="reset"]:-moz-focusring,
+ [type="submit"]:-moz-focusring {
+ outline: 1px dotted ButtonText; }
/**
- * Address Firefox 4+ setting `line-height` on `input` using `!important` in
- * the UA stylesheet.
- */
+ * Show the overflow in Edge.
+ */
input {
- line-height: normal; }
+ overflow: visible; }
/**
- * It's recommended that you don't attempt to style these elements.
- * Firefox's implementation doesn't respect box-sizing, padding, or width.
- *
- * 1. Address box sizing set to `content-box` in IE 8/9/10.
- * 2. Remove excess padding in IE 8/9/10.
- */
-input[type="checkbox"],
-input[type="radio"] {
+ * 1. Add the correct box sizing in IE 10-.
+ * 2. Remove the padding in IE 10-.
+ */
+[type="checkbox"],
+[type="radio"] {
box-sizing: border-box;
/* 1 */
padding: 0;
/* 2 */ }
/**
- * Fix the cursor style for Chrome's increment/decrement buttons. For certain
- * `font-size` values of the `input`, it causes the cursor style of the
- * decrement button to change from `default` to `text`.
- */
-input[type="number"]::-webkit-inner-spin-button,
-input[type="number"]::-webkit-outer-spin-button {
+ * Correct the cursor style of increment and decrement buttons in Chrome.
+ */
+[type="number"]::-webkit-inner-spin-button,
+[type="number"]::-webkit-outer-spin-button {
height: auto; }
/**
- * 1. Address `appearance` set to `searchfield` in Safari and Chrome.
- * 2. Address `box-sizing` set to `border-box` in Safari and Chrome.
- */
-input[type="search"] {
+ * 1. Correct the odd appearance in Chrome and Safari.
+ * 2. Correct the outline style in Safari.
+ */
+[type="search"] {
-webkit-appearance: textfield;
/* 1 */
- box-sizing: content-box;
- /* 2 */ }
+ outline-offset: -2px;
+ /* 2 */
+ /**
+ * Remove the inner padding and cancel buttons in Chrome and Safari on macOS.
+ */ }
+ [type="search"]::-webkit-search-cancel-button, [type="search"]::-webkit-search-decoration {
+ -webkit-appearance: none; }
/**
- * Remove inner padding and search cancel button in Safari and Chrome on OS X.
- * Safari (but not Chrome) clips the cancel button when the search input has
- * padding (and `textfield` appearance).
- */
-input[type="search"]::-webkit-search-cancel-button,
-input[type="search"]::-webkit-search-decoration {
- -webkit-appearance: none; }
+ * 1. Correct the inability to style clickable types in iOS and Safari.
+ * 2. Change font properties to `inherit` in Safari.
+ */
+::-webkit-file-upload-button {
+ -webkit-appearance: button;
+ /* 1 */
+ font: inherit;
+ /* 2 */ }
/**
- * Define consistent border, margin, and padding.
- * [NOTE] We don't enable this ruleset in Foundation, because we want the