first commit

This commit is contained in:
armansansd
2023-07-12 16:31:19 +01:00
commit 3424b1927b
23306 changed files with 2217776 additions and 0 deletions
+16
View File
@@ -0,0 +1,16 @@
# For more information about the properties used in
# this file, please see the EditorConfig documentation:
# http://editorconfig.org/
root = true
[*]
charset = utf-8
end_of_line = lf
indent_size = 2
indent_style = space
insert_final_newline = true
trim_trailing_whitespace = true
[*.md]
trim_trailing_whitespace = false
+5
View File
@@ -0,0 +1,5 @@
{
"semi": false,
"singleQuote": true,
"tabWidth": 2
}
+174
View File
@@ -0,0 +1,174 @@
/*
* load plugins
*/
const pkg = require('./package.json')
const banner = [
'/**',
' * <%= pkg.name %> - <%= pkg.description %>',
' * @version v<%= pkg.version %>',
' * @link <%= pkg.homepage %>',
' * @license <%= pkg.license %>',
' */',
''
].join('\n')
// gulp
const gulp = require('gulp')
// load all plugins in "devDependencies" into the letiable $
const $ = require('gulp-load-plugins')({
pattern: ['*'],
scope: ['devDependencies']
})
/*
* clean task
*/
gulp.task('clean', () => {
return $.del(['**/.DS_Store', './build/*', './dist/*'])
})
/*
* scripts tasks
*/
gulp.task('scripts', () => {
return gulp
.src(['./src/scripts/what-input.js'])
.pipe($.standard())
.pipe(
$.standard.reporter('default', {
breakOnError: true,
quiet: false
})
)
.pipe(
$.webpackStream({
module: {
loaders: [
{
test: /.jsx?$/,
loader: 'babel-loader',
exclude: /node_modules/,
query: {
presets: ['env']
}
}
]
},
output: {
chunkFilename: '[name].js',
library: 'whatInput',
libraryTarget: 'umd',
umdNamedDefine: true
}
})
)
.pipe($.rename('what-input.js'))
.pipe($.header(banner, { pkg: pkg }))
.pipe(gulp.dest('./dist/'))
.pipe(gulp.dest('./build/scripts/'))
.pipe($.sourcemaps.init())
.pipe($.uglify())
.pipe(
$.rename({
suffix: '.min'
})
)
.pipe($.header(banner, { pkg: pkg }))
.pipe($.sourcemaps.write('./maps'))
.pipe(gulp.dest('./dist/'))
.pipe($.notify('Build complete'))
})
/*
* stylesheets
*/
gulp.task('styles', () => {
let processors = [
$.autoprefixer({
browsers: ['last 3 versions', '> 1%', 'ie >= 10']
}),
$.cssMqpacker({
sort: true
})
]
return gulp
.src(['./src/styles/index.scss'])
.pipe(
$.plumber({
errorHandler: $.notify.onError('Error: <%= error.message %>')
})
)
.pipe($.sourcemaps.init())
.pipe($.sassGlob())
.pipe($.sass())
.pipe($.postcss(processors))
.pipe(
$.cssnano({
minifySelectors: false,
reduceIdents: false,
zindex: false
})
)
.pipe($.sourcemaps.write('maps'))
.pipe(gulp.dest('./build/styles'))
.pipe($.browserSync.stream())
.pipe($.notify('Styles task complete'))
})
/*
* images task
*/
gulp.task('images', () => {
return gulp.src(['./src/images/**/*']).pipe(gulp.dest('./build/images'))
})
/*
* markup task
*/
gulp.task('markup', () => {
return gulp.src(['./src/markup/*']).pipe(gulp.dest('./build'))
})
/*
* deploy task
*/
gulp.task('deploy', () => {
return gulp.src('./build/**/*').pipe($.ghPages())
})
/*
* default task
*/
gulp.task('default', () => {
$.runSequence('clean', ['markup', 'scripts', 'styles', 'images'], () => {
$.browserSync.init({
server: {
baseDir: './build/'
}
})
gulp
.watch(
['./src/scripts/what-input.js', './src/scripts/polyfills/*.js'],
['scripts']
)
.on('change', $.browserSync.reload)
gulp.watch(['./src/styles/{,*/}{,*/}*.scss'], ['styles'])
gulp
.watch(['./src/markup/*.html'], ['markup'])
.on('change', $.browserSync.reload)
})
})
+21
View File
@@ -0,0 +1,21 @@
The MIT License (MIT)
Copyright (c) 2016 Jeremy Fields
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.
+247
View File
@@ -0,0 +1,247 @@
# What Input?
**A global utility for tracking the current input method (mouse, keyboard or touch).**
## What Input is now v5
Now with more information and less opinion!
What Input adds data attributes to the `window` based on the type of input being used. It also exposes a simple API that can be used for scripting interactions.
## How it works
What Input uses event bubbling on the `window` to watch for mouse, keyboard and touch events (via `mousedown`, `keydown` and `touchstart`). It then sets or updates a `data-whatinput` attribute.
Pointer Events are supported but note that `pen` inputs are remapped to `touch`.
What Input also exposes a tiny API that allows the developer to ask for the current input, set custom ignore keys, and set and remove custom callback functions.
_What Input does not make assumptions about the input environment before the page is interacted with._ However, the `mousemove` and `pointermove` events are used to set a `data-whatintent="mouse"` attribute to indicate that a mouse is being used _indirectly_.
## Demo
Check out the demo to see What Input in action.
https://ten1seven.github.io/what-input
### Interacting with Forms
Since interacting with a form _always_ requires use of the keyboard, What Input uses the `data-whatintent` attribute to display a "buffered" version of input events while form `<input>`s, `<select>`s, and `<textarea>`s are being interacted with (i.e. mouse user's `data-whatintent` will be preserved as `mouse` while typing).
## Installing
Download the file directly.
Install via Yarn:
```shell
yarn add what-input
```
Install via NPM:
```shell
npm install what-input
```
## Usage
Include the script directly in your project.
```html
<script src="path/to/what-input.js"></script>
```
Or require with a script loader.
```javascript
import 'what-input'
// or
import whatInput from 'what-input'
// or
require('what-input')
// or
var whatInput = require('what-input')
// or
requirejs.config({
paths: {
whatInput: 'path/to/what-input'
}
})
require(['whatInput'], function() {})
```
What Input will start doing its thing while you do yours.
### Basic Styling
```css
/*
* only suppress the focus ring once what-input has successfully started
*/
/* suppress focus ring on form controls for mouse users */
[data-whatintent='mouse'] *:focus {
outline: none;
}
```
**Note:** If you remove outlines with `outline: none;`, be sure to provide clear visual `:focus` styles so the user can see which element they are on at any time for greater accessibility. Visit [W3C's WCAG 2.0 2.4.7 Guideline](https://www.w3.org/TR/UNDERSTANDING-WCAG20/navigation-mechanisms-focus-visible.html) to learn more.
### Scripting
#### Current Input
Ask What Input what the current input method is. This works best if asked after the events What Input is bound to (`mousedown`, `keydown` and `touchstart`).
```javascript
whatInput.ask() // returns `mouse`, `keyboard` or `touch`
myButton.addEventListener('click', () => {
if (whatInput.ask() === 'mouse') {
// do mousy things
} else if (whatInput.ask() === 'keyboard') {
// do keyboard things
}
})
```
If it's necessary to know if `mousemove` is being used, use the `'intent'` option. For example:
```javascript
/*
* nothing has happened but the mouse has moved
*/
whatInput.ask() // returns `initial` because the page has not been directly interacted with
whatInput.ask('intent') // returns `mouse` because mouse movement was detected
/*
* the keyboard has been used, then the mouse was moved
*/
whatInput.ask() // returns `keyboard` because the keyboard was the last direct page interaction
whatInput.ask('intent') // returns `mouse` because mouse movement was the most recent action detected
```
### Current Element
Ask What Input the currently focused DOM element.
```javascript
whatInput.element() // returns a string, like `input` or null
```
#### Ignore Keys
Set a custom array of [keycodes](http://keycode.info/) that will be ignored (will not switch over to `keyboard`) when pressed. _A custom list will overwrite the default values._
```javascript
/*
* default ignored keys:
* 16, // shift
* 17, // control
* 18, // alt
* 91, // Windows key / left Apple cmd
* 93 // Windows menu / right Apple cmd
*/
whatInput.ignoreKeys([1, 2, 3])
```
#### Specific Keys
Set a custom array of [keycodes](http://keycode.info/) that will trigger the keyboard pressed intent (will not switch to `keyboard` unless these keys are pressed). _This overrides ignoreKeys._
```javascript
// only listen to tab keyboard press
whatInput.specificKeys([9])
```
#### Custom Callbacks
Fire a function when the input or intent changes.
```javascript
// create a function to be fired
var myFunction = function(type) {
console.log(type)
}
// fire `myFunction` when the intent changes
whatInput.registerOnChange(myFunction, 'intent')
// fire `myFunction` when the input changes
whatInput.registerOnChange(myFunction, 'input')
// remove custom event
whatInput.unRegisterOnChange(myFunction)
```
## Compatibility
What Input works in all modern browsers.
## Changelog
### v5.1.3
- **Added:** Sourcemap for the minified version.
### v5.1.2
- **Added:** `specificKeys` functionality to allow overriding of keyboard keys list. Fix via [bk3](https://github.com/bk3).
### v5.1.1
- **Fixed:** Browsers with cookies turned off would throw an error with session storage. Fix via [yuheiy](https://github.com/yuheiy).
### v5.1.0
- **Added:** Session variable stores last used input and intent so subsiquent page loads don't have to wait for interactions to set the correct input and intent state.
- **Removed:** IE8 support.
### v5.0.7
- **Fixed:** `unRegisterOnChange` failed to unregister items at index 0.
### v5.0.5
- **Fixed:** Fail gracefully in non-DOM environments.
### v5.0.3
- **Fixed:** Event buffer for touch was not working correctly.
### Changes from v4
- **Added:** A the ability to add and remove custom callback function when the input or intent changes with `whatInput.registerOnChange` and `whatInput.unRegisterOnChange`.
- **Added:** A `data-whatelement` attribute exposes any currently focused DOM element (i.e. `data-whatelement="a"` or `data-whatelement="input"`).
- **Added:** A `data-whatclasses` attribute exposes any currently focused element's classes as a comma-separated list (i.e. `data-whatclasses="class1,class2"`).
- **Added:** An API option to provide a custom array of keycodes that will be ignored.
- **Changed:** Typing in form fields is no longer filtered out. The `data-whatinput` attribute immediately reflects the current input. The `data-whatintent` attribute now takes on the role of remembering mouse input prior to typing in or clicking on a form field.
- **Changed:** If you use the Tab key to move from one input to another one - the `data-whatinput` attribute reflects the current input (switches to "keyboard").
- **Removed:** `whatInput.types()` API option.
- **Removed:** Bower support.
- **Fixed:** Using mouse modifier keys (`shift`, `control`, `alt`, `cmd`) no longer toggles back to keyboard.
## Acknowledgments
Special thanks to [Viget](http://viget.com/) for their encouragement and commitment to open source projects. Visit [code.viget.com](http://code.viget.com/) to see more projects from [Viget](http://viget.com).
Thanks to [mAAdhaTTah](https://github.com/mAAdhaTTah) for the initial conversion to Webpack.
What Input is written and maintained by [@ten1seven](https://github.com/ten1seven).
## License
What Input is freely available under the [MIT License](http://opensource.org/licenses/MIT).
File diff suppressed because one or more lines are too long
+481
View File
@@ -0,0 +1,481 @@
/**
* what-input - A global utility for tracking the current input method (mouse, keyboard or touch).
* @version v5.1.4
* @link https://github.com/ten1seven/what-input
* @license MIT
*/
(function webpackUniversalModuleDefinition(root, factory) {
if(typeof exports === 'object' && typeof module === 'object')
module.exports = factory();
else if(typeof define === 'function' && define.amd)
define("whatInput", [], factory);
else if(typeof exports === 'object')
exports["whatInput"] = factory();
else
root["whatInput"] = factory();
})(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] = {
/******/ exports: {},
/******/ id: moduleId,
/******/ loaded: false
/******/ };
/******/ // Execute the module function
/******/ modules[moduleId].call(module.exports, module, module.exports, __webpack_require__);
/******/ // Flag the module as loaded
/******/ module.loaded = 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;
/******/ // __webpack_public_path__
/******/ __webpack_require__.p = "";
/******/ // Load entry module and return exports
/******/ return __webpack_require__(0);
/******/ })
/************************************************************************/
/******/ ([
/* 0 */
/***/ (function(module, exports) {
'use strict';
module.exports = function () {
/*
* bail out if there is no document or window
* (i.e. in a node/non-DOM environment)
*
* Return a stubbed API instead
*/
if (typeof document === 'undefined' || typeof window === 'undefined') {
return {
// always return "initial" because no interaction will ever be detected
ask: function ask() {
return 'initial';
},
// always return null
element: function element() {
return null;
},
// no-op
ignoreKeys: function ignoreKeys() {},
// no-op
specificKeys: function specificKeys() {},
// no-op
registerOnChange: function registerOnChange() {},
// no-op
unRegisterOnChange: function unRegisterOnChange() {}
};
}
/*
* variables
*/
// cache document.documentElement
var docElem = document.documentElement;
// currently focused dom element
var currentElement = null;
// last used input type
var currentInput = 'initial';
// last used input intent
var currentIntent = currentInput;
// check for sessionStorage support
// then check for session variables and use if available
try {
if (window.sessionStorage.getItem('what-input')) {
currentInput = window.sessionStorage.getItem('what-input');
}
if (window.sessionStorage.getItem('what-intent')) {
currentIntent = window.sessionStorage.getItem('what-intent');
}
} catch (e) {}
// event buffer timer
var eventTimer = null;
// form input types
var formInputs = ['input', 'select', 'textarea'];
// empty array for holding callback functions
var functionList = [];
// list of modifier keys commonly used with the mouse and
// can be safely ignored to prevent false keyboard detection
var ignoreMap = [16, // shift
17, // control
18, // alt
91, // Windows key / left Apple cmd
93 // Windows menu / right Apple cmd
];
var specificMap = [];
// mapping of events to input types
var inputMap = {
keydown: 'keyboard',
keyup: 'keyboard',
mousedown: 'mouse',
mousemove: 'mouse',
MSPointerDown: 'pointer',
MSPointerMove: 'pointer',
pointerdown: 'pointer',
pointermove: 'pointer',
touchstart: 'touch',
touchend: 'touch'
// boolean: true if touch buffer is active
};var isBuffering = false;
// boolean: true if the page is being scrolled
var isScrolling = false;
// store current mouse position
var mousePos = {
x: null,
y: null
// map of IE 10 pointer events
};var pointerMap = {
2: 'touch',
3: 'touch', // treat pen like touch
4: 'mouse'
// check support for passive event listeners
};var supportsPassive = false;
try {
var opts = Object.defineProperty({}, 'passive', {
get: function get() {
supportsPassive = true;
}
});
window.addEventListener('test', null, opts);
} catch (e) {}
/*
* set up
*/
var setUp = function setUp() {
// add correct mouse wheel event mapping to `inputMap`
inputMap[detectWheel()] = 'mouse';
addListeners();
doUpdate('input');
doUpdate('intent');
};
/*
* events
*/
var addListeners = function addListeners() {
// `pointermove`, `MSPointerMove`, `mousemove` and mouse wheel event binding
// can only demonstrate potential, but not actual, interaction
// and are treated separately
var options = supportsPassive ? { passive: true } : false;
// pointer events (mouse, pen, touch)
if (window.PointerEvent) {
window.addEventListener('pointerdown', setInput);
window.addEventListener('pointermove', setIntent);
} else if (window.MSPointerEvent) {
window.addEventListener('MSPointerDown', setInput);
window.addEventListener('MSPointerMove', setIntent);
} else {
// mouse events
window.addEventListener('mousedown', setInput);
window.addEventListener('mousemove', setIntent);
// touch events
if ('ontouchstart' in window) {
window.addEventListener('touchstart', eventBuffer, options);
window.addEventListener('touchend', setInput);
}
}
// mouse wheel
window.addEventListener(detectWheel(), setIntent, options);
// keyboard events
window.addEventListener('keydown', eventBuffer);
window.addEventListener('keyup', eventBuffer);
// focus events
window.addEventListener('focusin', setElement);
window.addEventListener('focusout', clearElement);
};
// checks conditions before updating new input
var setInput = function setInput(event) {
// only execute if the event buffer timer isn't running
if (!isBuffering) {
var eventKey = event.which;
var value = inputMap[event.type];
if (value === 'pointer') {
value = pointerType(event);
}
var ignoreMatch = !specificMap.length && ignoreMap.indexOf(eventKey) === -1;
var specificMatch = specificMap.length && specificMap.indexOf(eventKey) !== -1;
var shouldUpdate = value === 'keyboard' && eventKey && (ignoreMatch || specificMatch) || value === 'mouse' || value === 'touch';
if (currentInput !== value && shouldUpdate) {
currentInput = value;
try {
window.sessionStorage.setItem('what-input', currentInput);
} catch (e) {}
doUpdate('input');
}
if (currentIntent !== value && shouldUpdate) {
// preserve intent for keyboard typing in form fields
var activeElem = document.activeElement;
var notFormInput = activeElem && activeElem.nodeName && formInputs.indexOf(activeElem.nodeName.toLowerCase()) === -1;
if (notFormInput) {
currentIntent = value;
try {
window.sessionStorage.setItem('what-intent', currentIntent);
} catch (e) {}
doUpdate('intent');
}
}
}
};
// updates the doc and `inputTypes` array with new input
var doUpdate = function doUpdate(which) {
docElem.setAttribute('data-what' + which, which === 'input' ? currentInput : currentIntent);
fireFunctions(which);
};
// updates input intent for `mousemove` and `pointermove`
var setIntent = function setIntent(event) {
// test to see if `mousemove` happened relative to the screen to detect scrolling versus mousemove
detectScrolling(event);
// only execute if the event buffer timer isn't running
// or scrolling isn't happening
if (!isBuffering && !isScrolling) {
var value = inputMap[event.type];
if (value === 'pointer') {
value = pointerType(event);
}
if (currentIntent !== value) {
currentIntent = value;
try {
window.sessionStorage.setItem('what-intent', currentIntent);
} catch (e) {}
doUpdate('intent');
}
}
};
var setElement = function setElement(event) {
if (!event.target.nodeName) {
// If nodeName is undefined, clear the element
// This can happen if click inside an <svg> element.
clearElement();
return;
}
currentElement = event.target.nodeName.toLowerCase();
docElem.setAttribute('data-whatelement', currentElement);
if (event.target.classList && event.target.classList.length) {
docElem.setAttribute('data-whatclasses', event.target.classList.toString().replace(' ', ','));
}
};
var clearElement = function clearElement() {
currentElement = null;
docElem.removeAttribute('data-whatelement');
docElem.removeAttribute('data-whatclasses');
};
// buffers events that frequently also fire mouse events
var eventBuffer = function eventBuffer(event) {
// set the current input
setInput(event);
// clear the timer if it happens to be running
window.clearTimeout(eventTimer);
// set the isBuffering to `true`
isBuffering = true;
// run the timer
eventTimer = window.setTimeout(function () {
// if the timer runs out, set isBuffering back to `false`
isBuffering = false;
}, 120);
};
/*
* utilities
*/
var pointerType = function pointerType(event) {
if (typeof event.pointerType === 'number') {
return pointerMap[event.pointerType];
} else {
// treat pen like touch
return event.pointerType === 'pen' ? 'touch' : event.pointerType;
}
};
// detect version of mouse wheel event to use
// via https://developer.mozilla.org/en-US/docs/Web/Events/wheel
var detectWheel = function detectWheel() {
var wheelType = void 0;
// Modern browsers support "wheel"
if ('onwheel' in document.createElement('div')) {
wheelType = 'wheel';
} else {
// Webkit and IE support at least "mousewheel"
// or assume that remaining browsers are older Firefox
wheelType = document.onmousewheel !== undefined ? 'mousewheel' : 'DOMMouseScroll';
}
return wheelType;
};
// runs callback functions
var fireFunctions = function fireFunctions(type) {
for (var i = 0, len = functionList.length; i < len; i++) {
if (functionList[i].type === type) {
functionList[i].fn.call(undefined, type === 'input' ? currentInput : currentIntent);
}
}
};
// finds matching element in an object
var objPos = function objPos(match) {
for (var i = 0, len = functionList.length; i < len; i++) {
if (functionList[i].fn === match) {
return i;
}
}
};
var detectScrolling = function detectScrolling(event) {
if (mousePos['x'] !== event.screenX || mousePos['y'] !== event.screenY) {
isScrolling = false;
mousePos['x'] = event.screenX;
mousePos['y'] = event.screenY;
} else {
isScrolling = true;
}
};
/*
* init
*/
// don't start script unless browser cuts the mustard
// (also passes if polyfills are used)
if ('addEventListener' in window && Array.prototype.indexOf) {
setUp();
}
/*
* api
*/
return {
// returns string: the current input type
// opt: 'intent'|'input'
// 'input' (default): returns the same value as the `data-whatinput` attribute
// 'intent': includes `data-whatintent` value if it's different than `data-whatinput`
ask: function ask(opt) {
return opt === 'intent' ? currentIntent : currentInput;
},
// returns string: the currently focused element or null
element: function element() {
return currentElement;
},
// overwrites ignored keys with provided array
ignoreKeys: function ignoreKeys(arr) {
ignoreMap = arr;
},
// overwrites specific char keys to update on
specificKeys: function specificKeys(arr) {
specificMap = arr;
},
// attach functions to input and intent "events"
// funct: function to fire on change
// eventType: 'input'|'intent'
registerOnChange: function registerOnChange(fn, eventType) {
functionList.push({
fn: fn,
type: eventType || 'input'
});
},
unRegisterOnChange: function unRegisterOnChange(fn) {
var position = objPos(fn);
if (position || position === 0) {
functionList.splice(position, 1);
}
}
};
}();
/***/ })
/******/ ])
});
;
+8
View File
@@ -0,0 +1,8 @@
/**
* what-input - A global utility for tracking the current input method (mouse, keyboard or touch).
* @version v5.1.4
* @link https://github.com/ten1seven/what-input
* @license MIT
*/
!function(e,t){"object"==typeof exports&&"object"==typeof module?module.exports=t():"function"==typeof define&&define.amd?define("whatInput",[],t):"object"==typeof exports?exports.whatInput=t():e.whatInput=t()}(this,function(){return function(n){var o={};function i(e){if(o[e])return o[e].exports;var t=o[e]={exports:{},id:e,loaded:!1};return n[e].call(t.exports,t,t.exports,i),t.loaded=!0,t.exports}return i.m=n,i.c=o,i.p="",i(0)}([function(e,t){"use strict";e.exports=function(){if("undefined"==typeof document||"undefined"==typeof window)return{ask:function(){return"initial"},element:function(){return null},ignoreKeys:function(){},specificKeys:function(){},registerOnChange:function(){},unRegisterOnChange:function(){}};var t=document.documentElement,n=null,s="initial",a=s;try{window.sessionStorage.getItem("what-input")&&(s=window.sessionStorage.getItem("what-input")),window.sessionStorage.getItem("what-intent")&&(a=window.sessionStorage.getItem("what-intent"))}catch(e){}var o=null,d=["input","select","textarea"],i=[],c=[16,17,18,91,93],w=[],f={keydown:"keyboard",keyup:"keyboard",mousedown:"mouse",mousemove:"mouse",MSPointerDown:"pointer",MSPointerMove:"pointer",pointerdown:"pointer",pointermove:"pointer",touchstart:"touch",touchend:"touch"},p=!1,r=!1,u={x:null,y:null},l={2:"touch",3:"touch",4:"mouse"},h=!1;try{var e=Object.defineProperty({},"passive",{get:function(){h=!0}});window.addEventListener("test",null,e)}catch(e){}var m=function(){var e=!!h&&{passive:!0};window.PointerEvent?(window.addEventListener("pointerdown",v),window.addEventListener("pointermove",g)):window.MSPointerEvent?(window.addEventListener("MSPointerDown",v),window.addEventListener("MSPointerMove",g)):(window.addEventListener("mousedown",v),window.addEventListener("mousemove",g),"ontouchstart"in window&&(window.addEventListener("touchstart",x,e),window.addEventListener("touchend",v))),window.addEventListener(b(),g,e),window.addEventListener("keydown",x),window.addEventListener("keyup",x),window.addEventListener("focusin",E),window.addEventListener("focusout",L)},v=function(e){if(!p){var t=e.which,n=f[e.type];"pointer"===n&&(n=S(e));var o=!w.length&&-1===c.indexOf(t),i=w.length&&-1!==w.indexOf(t),r="keyboard"===n&&t&&(o||i)||"mouse"===n||"touch"===n;if(s!==n&&r){s=n;try{window.sessionStorage.setItem("what-input",s)}catch(e){}y("input")}if(a!==n&&r){var u=document.activeElement;if(u&&u.nodeName&&-1===d.indexOf(u.nodeName.toLowerCase())){a=n;try{window.sessionStorage.setItem("what-intent",a)}catch(e){}y("intent")}}}},y=function(e){t.setAttribute("data-what"+e,"input"===e?s:a),I(e)},g=function(e){if(O(e),!p&&!r){var t=f[e.type];if("pointer"===t&&(t=S(e)),a!==t){a=t;try{window.sessionStorage.setItem("what-intent",a)}catch(e){}y("intent")}}},E=function(e){e.target.nodeName?(n=e.target.nodeName.toLowerCase(),t.setAttribute("data-whatelement",n),e.target.classList&&e.target.classList.length&&t.setAttribute("data-whatclasses",e.target.classList.toString().replace(" ",","))):L()},L=function(){n=null,t.removeAttribute("data-whatelement"),t.removeAttribute("data-whatclasses")},x=function(e){v(e),window.clearTimeout(o),p=!0,o=window.setTimeout(function(){p=!1},120)},S=function(e){return"number"==typeof e.pointerType?l[e.pointerType]:"pen"===e.pointerType?"touch":e.pointerType},b=function(){return"onwheel"in document.createElement("div")?"wheel":void 0!==document.onmousewheel?"mousewheel":"DOMMouseScroll"},I=function(e){for(var t=0,n=i.length;t<n;t++)i[t].type===e&&i[t].fn.call(void 0,"input"===e?s:a)},O=function(e){u.x!==e.screenX||u.y!==e.screenY?(r=!1,u.x=e.screenX,u.y=e.screenY):r=!0};return"addEventListener"in window&&Array.prototype.indexOf&&(f[b()]="mouse",m(),y("input"),y("intent")),{ask:function(e){return"intent"===e?a:s},element:function(){return n},ignoreKeys:function(e){c=e},specificKeys:function(e){w=e},registerOnChange:function(e,t){i.push({fn:e,type:t||"input"})},unRegisterOnChange:function(e){var t=function(e){for(var t=0,n=i.length;t<n;t++)if(i[t].fn===e)return t}(e);(t||0===t)&&i.splice(t,1)}}}()}])});
//# sourceMappingURL=maps/what-input.min.js.map
+81
View File
@@ -0,0 +1,81 @@
{
"_from": "what-input@^5.1.4",
"_id": "what-input@5.1.4",
"_inBundle": false,
"_integrity": "sha512-RXfKhZ5t2j5iNuhyZY9psuC82Ped4YYU38McO++wxdLXHiJprK8YJgUpfBjgKCQvLKLLpsi/KnEckWaZn5IzzQ==",
"_location": "/what-input",
"_phantomChildren": {},
"_requested": {
"type": "range",
"registry": true,
"raw": "what-input@^5.1.4",
"name": "what-input",
"escapedName": "what-input",
"rawSpec": "^5.1.4",
"saveSpec": null,
"fetchSpec": "^5.1.4"
},
"_requiredBy": [
"#DEV:/",
"#USER"
],
"_resolved": "https://registry.npmjs.org/what-input/-/what-input-5.1.4.tgz",
"_shasum": "075b1af66b558b6972ed717c29874082a282bf0e",
"_spec": "what-input@^5.1.4",
"_where": "/srv/http/mmap_sarrebourg/user/themes/basic",
"author": {
"name": "Jeremy Fields",
"email": "jeremy.fields@viget.com"
},
"bugs": {
"url": "https://github.com/ten1seven/what-input/issues"
},
"bundleDependencies": false,
"deprecated": false,
"description": "A global utility for tracking the current input method (mouse, keyboard or touch).",
"devDependencies": {
"autoprefixer": "^9.3.1",
"babel-core": "^6.23.1",
"babel-loader": "^6.3.2",
"babel-preset-env": "^1.6.0",
"browser-sync": "^2.26.3",
"css-mqpacker": "^7.0.0",
"del": "^3.0.0",
"gulp": "^3.9.1",
"gulp-concat": "^2.6.1",
"gulp-cssnano": "^2.1.3",
"gulp-gh-pages": "^0.5.4",
"gulp-header": "1.7.1",
"gulp-load-plugins": "^1.5.0",
"gulp-notify": "2.2.0",
"gulp-plumber": "1.1.0",
"gulp-postcss": "^8.0.0",
"gulp-rename": "^1.4.0",
"gulp-sass": "^4.0.2",
"gulp-sass-glob": "^1.0.9",
"gulp-sourcemaps": "^2.6.4",
"gulp-standard": "^8.0.4",
"gulp-uglify": "^3.0.1",
"run-sequence": "^2.2.1",
"webpack-stream": "3.2.0"
},
"homepage": "https://github.com/ten1seven/what-input",
"keywords": [
"accessibility",
"a11y",
"input",
"javascript"
],
"license": "MIT",
"main": "dist/what-input.js",
"name": "what-input",
"repository": {
"url": "git+https://github.com/ten1seven/what-input.git",
"type": "git"
},
"scripts": {
"deploy": "gulp deploy",
"start": "gulp"
},
"version": "5.1.4"
}
+1
View File
@@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="40.941" height="24" viewBox="0 0 40.941 24"><defs><path id="a" d="M0 0h40.94v24H0z"/></defs><clipPath id="b"><use xlink:href="#a" overflow="visible"/></clipPath><path fill="#555" clip-path="url(#b)" d="M1.116 6.93C2.556 8.404 17.69 22.82 17.69 22.82c.768.785 1.773 1.18 2.78 1.18 1.008 0 2.014-.395 2.78-1.18 0 0 15.136-14.416 16.574-15.89 1.44-1.476 1.536-4.13 0-5.703-1.535-1.573-3.678-1.7-5.56 0L20.47 14.453 6.678 1.23C4.794-.47 2.65-.346 1.116 1.227c-1.537 1.574-1.44 4.227 0 5.702"/></svg>

After

Width:  |  Height:  |  Size: 586 B

+119
View File
@@ -0,0 +1,119 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>What Input?</title>
<link
rel="stylesheet"
href="styles/index.css">
</head>
<body>
<div class="container">
<h1>What Input?</h1>
<p class="lede">
A global utility for tracking the current input method (<span class="input-indicator -mouse">mouse</span>, <span class="input-indicator -keyboard">keyboard</span> or <span class="input-indicator -touch">touch</span>), as well as the current <em>intent</em> (<span class="input-intent -mouse">mouse</span> or <span class="input-intent -keyboard">keyboard</span>).
</p>
<p>
Tab, click or tap the links and form controls to see how What Input allows them to be styled differently.
</p>
<div class="well">
<div class="well-row">
<div class="well-column">
<ul class="list-group">
<li class="list-group-item"><a href="#">Cras justo odio</a></li>
<li class="list-group-item"><a href="#">Dapibus ac facilisis in</a></li>
<li class="list-group-item"><a href="#">Morbi leo risus</a></li>
<li class="list-group-item"><a href="#">Porta ac consectetur ac</a></li>
<li class="list-group-item"><a href="#">Vestibulum at eros</a></li>
</ul>
</div>
<form class="well-column">
<p>
<label for="exampleInput">Example Text Input</label>
<input
type="email"
id="exampleInput"
name="exampleInput">
</p>
<p>
<label for="exampleSelect">Selection</label>
<select id="exampleSelect" name="exampleSelect">
<option value="" disabled selected>Select an option</option>
<option>Option 1</option>
<option>Option 2</option>
<option>Option 3</option>
</select>
</p>
<p>
<label for="exampleTextarea">Example Textarea</label>
<textarea
id="exampleTextarea"
name="exampleTextarea"></textarea>
</p>
<p class="checkbox">
<label>
<input type="checkbox"> Check me out
</label>
</p>
<p>
<button type="submit">Submit</button>
</p>
</form>
</div>
</div>
<footer>
<p class="pull-left">
Made with <span class="text-love">&hearts;</span> at <a href="http://viget.com/">Viget</a>.
</p>
<p class="pull-right">
Check out the project <a href="https://github.com/ten1seven/what-input">on Github</a>.
</p>
</footer>
</div>
<script src="scripts/what-input.js"></script>
<script>
var links = document.querySelectorAll('a');
for (var i = 0, len = links.length; i < len; i++) {
links[i].addEventListener('click', function(event) {
console.log('[script test] ' + whatInput.ask() + ' ' + whatInput.element());
event.preventDefault();
})
}
var myInputFunction = function(type) {
console.log('input: ' + type)
};
var myIntentFunction = function(type) {
console.log('intent: ' + type)
};
whatInput.registerOnChange(myInputFunction);
whatInput.registerOnChange(myIntentFunction, 'intent');
var form = document.querySelector('form');
form.addEventListener('submit', function(event) {
event.preventDefault();
});
</script>
</body>
</html>
+430
View File
@@ -0,0 +1,430 @@
module.exports = (() => {
/*
* bail out if there is no document or window
* (i.e. in a node/non-DOM environment)
*
* Return a stubbed API instead
*/
if (typeof document === 'undefined' || typeof window === 'undefined') {
return {
// always return "initial" because no interaction will ever be detected
ask: () => 'initial',
// always return null
element: () => null,
// no-op
ignoreKeys: () => {},
// no-op
specificKeys: () => {},
// no-op
registerOnChange: () => {},
// no-op
unRegisterOnChange: () => {}
}
}
/*
* variables
*/
// cache document.documentElement
const docElem = document.documentElement
// currently focused dom element
let currentElement = null
// last used input type
let currentInput = 'initial'
// last used input intent
let currentIntent = currentInput
// check for sessionStorage support
// then check for session variables and use if available
try {
if (window.sessionStorage.getItem('what-input')) {
currentInput = window.sessionStorage.getItem('what-input')
}
if (window.sessionStorage.getItem('what-intent')) {
currentIntent = window.sessionStorage.getItem('what-intent')
}
} catch (e) {}
// event buffer timer
let eventTimer = null
// form input types
const formInputs = ['input', 'select', 'textarea']
// empty array for holding callback functions
let functionList = []
// list of modifier keys commonly used with the mouse and
// can be safely ignored to prevent false keyboard detection
let ignoreMap = [
16, // shift
17, // control
18, // alt
91, // Windows key / left Apple cmd
93 // Windows menu / right Apple cmd
]
let specificMap = []
// mapping of events to input types
const inputMap = {
keydown: 'keyboard',
keyup: 'keyboard',
mousedown: 'mouse',
mousemove: 'mouse',
MSPointerDown: 'pointer',
MSPointerMove: 'pointer',
pointerdown: 'pointer',
pointermove: 'pointer',
touchstart: 'touch',
touchend: 'touch'
}
// boolean: true if touch buffer is active
let isBuffering = false
// boolean: true if the page is being scrolled
let isScrolling = false
// store current mouse position
let mousePos = {
x: null,
y: null
}
// map of IE 10 pointer events
const pointerMap = {
2: 'touch',
3: 'touch', // treat pen like touch
4: 'mouse'
}
// check support for passive event listeners
let supportsPassive = false
try {
let opts = Object.defineProperty({}, 'passive', {
get: () => {
supportsPassive = true
}
})
window.addEventListener('test', null, opts)
} catch (e) {}
/*
* set up
*/
const setUp = () => {
// add correct mouse wheel event mapping to `inputMap`
inputMap[detectWheel()] = 'mouse'
addListeners()
doUpdate('input')
doUpdate('intent')
}
/*
* events
*/
const addListeners = () => {
// `pointermove`, `MSPointerMove`, `mousemove` and mouse wheel event binding
// can only demonstrate potential, but not actual, interaction
// and are treated separately
const options = supportsPassive ? { passive: true } : false
// pointer events (mouse, pen, touch)
if (window.PointerEvent) {
window.addEventListener('pointerdown', setInput)
window.addEventListener('pointermove', setIntent)
} else if (window.MSPointerEvent) {
window.addEventListener('MSPointerDown', setInput)
window.addEventListener('MSPointerMove', setIntent)
} else {
// mouse events
window.addEventListener('mousedown', setInput)
window.addEventListener('mousemove', setIntent)
// touch events
if ('ontouchstart' in window) {
window.addEventListener('touchstart', eventBuffer, options)
window.addEventListener('touchend', setInput)
}
}
// mouse wheel
window.addEventListener(detectWheel(), setIntent, options)
// keyboard events
window.addEventListener('keydown', eventBuffer)
window.addEventListener('keyup', eventBuffer)
// focus events
window.addEventListener('focusin', setElement)
window.addEventListener('focusout', clearElement)
}
// checks conditions before updating new input
const setInput = event => {
// only execute if the event buffer timer isn't running
if (!isBuffering) {
let eventKey = event.which
let value = inputMap[event.type]
if (value === 'pointer') {
value = pointerType(event)
}
const ignoreMatch =
!specificMap.length && ignoreMap.indexOf(eventKey) === -1
const specificMatch =
specificMap.length && specificMap.indexOf(eventKey) !== -1
let shouldUpdate =
(value === 'keyboard' && eventKey && (ignoreMatch || specificMatch)) ||
value === 'mouse' ||
value === 'touch'
if (currentInput !== value && shouldUpdate) {
currentInput = value
try {
window.sessionStorage.setItem('what-input', currentInput)
} catch (e) {}
doUpdate('input')
}
if (currentIntent !== value && shouldUpdate) {
// preserve intent for keyboard typing in form fields
let activeElem = document.activeElement
let notFormInput =
activeElem &&
activeElem.nodeName &&
formInputs.indexOf(activeElem.nodeName.toLowerCase()) === -1
if (notFormInput) {
currentIntent = value
try {
window.sessionStorage.setItem('what-intent', currentIntent)
} catch (e) {}
doUpdate('intent')
}
}
}
}
// updates the doc and `inputTypes` array with new input
const doUpdate = which => {
docElem.setAttribute(
'data-what' + which,
which === 'input' ? currentInput : currentIntent
)
fireFunctions(which)
}
// updates input intent for `mousemove` and `pointermove`
const setIntent = event => {
// test to see if `mousemove` happened relative to the screen to detect scrolling versus mousemove
detectScrolling(event)
// only execute if the event buffer timer isn't running
// or scrolling isn't happening
if (!isBuffering && !isScrolling) {
let value = inputMap[event.type]
if (value === 'pointer') {
value = pointerType(event)
}
if (currentIntent !== value) {
currentIntent = value
try {
window.sessionStorage.setItem('what-intent', currentIntent)
} catch (e) {}
doUpdate('intent')
}
}
}
const setElement = event => {
if (!event.target.nodeName) {
// If nodeName is undefined, clear the element
// This can happen if click inside an <svg> element.
clearElement()
return
}
currentElement = event.target.nodeName.toLowerCase()
docElem.setAttribute('data-whatelement', currentElement)
if (event.target.classList && event.target.classList.length) {
docElem.setAttribute(
'data-whatclasses',
event.target.classList.toString().replace(' ', ',')
)
}
}
const clearElement = () => {
currentElement = null
docElem.removeAttribute('data-whatelement')
docElem.removeAttribute('data-whatclasses')
}
// buffers events that frequently also fire mouse events
const eventBuffer = event => {
// set the current input
setInput(event)
// clear the timer if it happens to be running
window.clearTimeout(eventTimer)
// set the isBuffering to `true`
isBuffering = true
// run the timer
eventTimer = window.setTimeout(() => {
// if the timer runs out, set isBuffering back to `false`
isBuffering = false
}, 120)
}
/*
* utilities
*/
const pointerType = event => {
if (typeof event.pointerType === 'number') {
return pointerMap[event.pointerType]
} else {
// treat pen like touch
return event.pointerType === 'pen' ? 'touch' : event.pointerType
}
}
// detect version of mouse wheel event to use
// via https://developer.mozilla.org/en-US/docs/Web/Events/wheel
const detectWheel = () => {
let wheelType
// Modern browsers support "wheel"
if ('onwheel' in document.createElement('div')) {
wheelType = 'wheel'
} else {
// Webkit and IE support at least "mousewheel"
// or assume that remaining browsers are older Firefox
wheelType =
document.onmousewheel !== undefined ? 'mousewheel' : 'DOMMouseScroll'
}
return wheelType
}
// runs callback functions
const fireFunctions = type => {
for (let i = 0, len = functionList.length; i < len; i++) {
if (functionList[i].type === type) {
functionList[i].fn.call(
this,
type === 'input' ? currentInput : currentIntent
)
}
}
}
// finds matching element in an object
const objPos = match => {
for (let i = 0, len = functionList.length; i < len; i++) {
if (functionList[i].fn === match) {
return i
}
}
}
const detectScrolling = event => {
if (mousePos['x'] !== event.screenX || mousePos['y'] !== event.screenY) {
isScrolling = false
mousePos['x'] = event.screenX
mousePos['y'] = event.screenY
} else {
isScrolling = true
}
}
/*
* init
*/
// don't start script unless browser cuts the mustard
// (also passes if polyfills are used)
if ('addEventListener' in window && Array.prototype.indexOf) {
setUp()
}
/*
* api
*/
return {
// returns string: the current input type
// opt: 'intent'|'input'
// 'input' (default): returns the same value as the `data-whatinput` attribute
// 'intent': includes `data-whatintent` value if it's different than `data-whatinput`
ask: opt => {
return opt === 'intent' ? currentIntent : currentInput
},
// returns string: the currently focused element or null
element: () => {
return currentElement
},
// overwrites ignored keys with provided array
ignoreKeys: arr => {
ignoreMap = arr
},
// overwrites specific char keys to update on
specificKeys: arr => {
specificMap = arr
},
// attach functions to input and intent "events"
// funct: function to fire on change
// eventType: 'input'|'intent'
registerOnChange: (fn, eventType) => {
functionList.push({
fn: fn,
type: eventType || 'input'
})
},
unRegisterOnChange: fn => {
let position = objPos(fn)
if (position || position === 0) {
functionList.splice(position, 1)
}
}
}
})()
+49
View File
@@ -0,0 +1,49 @@
*,
*::before,
*::after {
box-sizing: border-box;
}
html {
-webkit-tap-highlight-color: rgba(0, 0, 0, 0);
}
body {
color: #555;
font-family: 'Helvetica Neue', Helvetica, Arial, sans-serif;
margin: 0;
padding: 0;
}
a,
button,
input,
select,
textarea {
@include a11y-focus;
}
a {
color: #337ab7;
text-decoration: none;
@include hover {
text-decoration: underline;
}
}
h1 {
border-bottom: 1px solid #eee;
font-size: 36px;
font-weight: 500;
margin: 20px 0 10px;
padding-bottom: 9px;
}
p {
margin: ($unit * 2) 0;
@media (min-width: 800px) {
margin: ($unit * 3) 0;
}
}
+212
View File
@@ -0,0 +1,212 @@
.container {
box-sizing: content-box;
font-size: 14px;
line-height: 1.4;
margin: 0 auto;
padding: 0 ($unit * 2);
max-width: $container-width;
@media (min-width: 800px) {
padding: 0 ($unit * 3);
}
}
.lede {
font-size: 20px;
font-weight: 300;
line-height: ($unit * 4);
@media (min-width: 800px) {
font-size: 22px;
}
}
.well {
@include clearfix;
background-color: #f5f5f5;
border: 1px solid #e3e3e3;
border-radius: 4px;
margin: ($unit * 3) 0;
padding: ($unit * 3);
}
.well-row {
@media (min-width: 800px) {
display: flex;
margin-left: ($unit * -3);
}
}
.well-column {
@include null-margins;
@media (max-width: 799px) {
+ .well-column {
border-top: 1px solid #ccc;
margin-top: ($unit * 4);
padding-top: ($unit * 3);
}
}
@media (min-width: 800px) {
padding-left: ($unit * 3);
width: 50%;
}
}
.list-group {
list-style: none;
padding: 0;
}
.list-group-item {
&:first-child a {
border-radius: 4px 4px 0 0;
}
&:last-child a {
border-bottom: 1px solid #ddd;
border-radius: 0 0 4px 4px;
}
a {
@include a11y-focus;
background-color: #fff;
border: 1px solid #ddd;
border-bottom: none;
color: #555;
display: block;
padding: ($unit * 2) ($unit * 2);
text-decoration: none;
transition: all 0.2s ease;
@include hover {
background-color: #f5f5f5;
}
&:active,
&:focus {
position: relative;
}
}
}
form.well-column {
button {
appearance: none;
background-color: #337ab7;
border: 1px solid #2e6da4;
border-radius: 4px;
color: #fff;
cursor: pointer;
font-family: 'Helvetica Neue', Helvetica, Arial, sans-serif;
font-size: 14px;
font-weight: 400;
margin: 0;
padding: $unit ($unit * 2);
text-align: center;
transition: all 0.2s ease;
@include hover {
background-color: #286090;
border-color: #204d74;
}
}
label {
color: #333;
display: block;
font-size: 14px;
font-weight: 700;
line-height: ($unit * 3);
}
p {
margin: ($unit * 2) 0;
&.checkbox label {
font-weight: 400;
}
}
input {
&:not([type='submit']):not([type='checkbox']):not([type='radio']) {
@include input-style-base;
box-shadow: inset 0 1px 1px rgba(#000, 0.075);
transition: all 0.2s ease;
@include placeholder {
color: #999;
}
[data-whatintent='mouse'] &:focus {
border-color: #31708f;
box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075),
0 0 8px rgba(49, 112, 143, 0.6);
}
}
&[type='checkbox'],
&[type='radio'] {
outline: none;
}
}
select {
@include input-style-base;
background-image: url(../images/select-arrow.svg);
background-position: calc(100% - 10px) 50%;
background-repeat: no-repeat;
background-size: 10px 6px;
padding-right: 30px;
@media (min-width: 800px) {
min-width: 50%;
width: auto;
}
// hide arrow in IE
&::-ms-expand {
display: none;
}
}
textarea {
@include input-style-base;
box-shadow: inset 0 1px 1px rgba(#000, 0.075);
height: 5em;
padding-top: $unit;
padding-bottom: $unit;
transition: all 0.2s ease;
[data-whatintent='mouse'] &:focus {
border-color: #31708f;
box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075),
0 0 8px rgba(49, 112, 143, 0.6);
}
}
}
footer {
@include clearfix;
font-size: 14px;
margin: ($unit * 4) 0;
p {
margin: 0;
}
.text-love {
color: #a94442;
}
.pull-left {
float: left;
margin: 0;
}
.pull-right {
float: right;
margin: 0;
}
}
+70
View File
@@ -0,0 +1,70 @@
@mixin clearfix {
&::after {
clear: both;
content: '';
display: table;
}
}
@mixin null-margins {
> :first-child {
margin-top: 0 !important;
}
> :last-child {
margin-bottom: 0 !important;
}
}
@mixin hover {
&:focus,
&:hover {
@content;
}
}
@mixin a11y-focus {
&:active,
&:focus {
box-shadow: 0 0 0 3px orange !important;
outline: none !important;
}
[data-whatintent='mouse'] &:active,
[data-whatintent='mouse'] &:focus,
[data-whatintent='touch'] &:active,
[data-whatintent='touch'] &:focus {
box-shadow: none !important;
}
}
@mixin input-style-base {
appearance: none;
background-color: #fff;
border: 1px solid #ccc;
border-radius: 4px;
color: #555;
font-family: 'Helvetica Neue', Helvetica, Arial, sans-serif;
font-size: 16px;
height: ($unit * 4);
margin: 0;
padding: 0 $unit;
width: 100%;
}
@mixin placeholder {
&::-webkit-input-placeholder {
// Chrome/Opera/Safari
@content;
}
&::-moz-placeholder {
// Firefox 19+
@content;
}
&:-ms-input-placeholder {
// IE 10+
@content;
}
}
+2
View File
@@ -0,0 +1,2 @@
$unit: 8px;
$container-width: 1100px;
+50
View File
@@ -0,0 +1,50 @@
@import 'variables';
@import 'mixins';
@import 'html';
@import 'layout';
/*
* what-input styles
*/
// indicator
.input-indicator,
.input-intent {
border-radius: 3px;
display: inline-block;
padding: 0 3px;
transition: all 0.2s ease;
}
[data-whatinput='mouse'] .input-indicator.-mouse,
[data-whatintent='mouse'] .input-intent.-mouse {
background-color: rgba(#337ab7, 0.2);
box-shadow: 0 0 0 1px rgba(#337ab7, 0.3);
color: #337ab7;
}
[data-whatinput='keyboard'] .input-indicator.-keyboard,
[data-whatintent='keyboard'] .input-intent.-keyboard {
background-color: rgba(orange, 0.1);
box-shadow: 0 0 0 1px rgba(orange, 0.3);
color: orange;
}
[data-whatinput='touch'] .input-indicator.-touch {
background-color: rgba(#8a6d3b, 0.1);
box-shadow: 0 0 0 1px rgba(#8a6d3b, 0.3);
color: #8a6d3b;
}
// suppress focus outline for mouse and touch
[data-whatintent='mouse'],
[data-whatintent='touch'] {
*:focus {
outline: none;
}
}
// divs or sections with `tabindex`
html:not([data-whatinput='keyboard']) div:focus {
outline: none;
}
+7336
View File
File diff suppressed because it is too large Load Diff