Skip to content

Instantly share code, notes, and snippets.

@reecelucas
reecelucas / validate-email.js
Created July 2, 2018 20:31
Email validation utility
/**
* @param {String} email
* @return {Boolean}
*/
const validateEmail = email => {
const emailRegex = /^(([^<>()[\]\\.,;:\s@"]+(\.[^<>()[\]\\.,;:\s@"]+)*)|(".+"))@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$/;
return emailRegex.test(email);
};
/**
* @param {String} key
* @param {Any} value
* @param {Number} expirationDays
* @returns {void}
*/
export const saveToLocalStorage = ({ key, value, expirationDays }) => {
// Try for localStorage support...
try {
// Convert days to milliseconds (ms)
@reecelucas
reecelucas / register-sw.js
Created July 2, 2018 20:49
Register a service worker
if ('serviceWorker' in navigator) {
window.addEventListener('load', function() {
navigator.serviceWorker
.register('path/to/service-worker.js')
.then(registration => {
console.log('SW registered: ', registration);
})
.catch(registrationError => {
console.log('SW registration failed: ', registrationError);
});
@reecelucas
reecelucas / observe-visibility.js
Last active August 27, 2018 21:03
Snippet to observe when elements are visible in the viewport, using the IntersectionObserver API
const config = {
selector: '[data-observe]',
isVisibleClass: 'is-visible',
observerOptions: {
threshold: 0,
rootId: null,
rootMargin: '0px 0px 0px 0px',
once: true
}
};
@reecelucas
reecelucas / accordion.js
Last active September 20, 2018 09:30
Simple accessible multi-select accordion. Modified from: https://inclusive-components.design/collapsible-sections/
const config = {
accordionSelector: "[data-accordion]",
headingSelector: "[data-accordion-heading]",
buttonSelector: "[data-accordion-button]"
};
const setup = accordion => {
const headings = [...accordion.querySelectorAll(config.headingSelector)];
if (!headings || headings.length === 0) return;
@reecelucas
reecelucas / HTML5-form-validation.js
Last active September 30, 2018 15:15
Simple & extensible form validation using the HTML5 constraint validation API
const form = document.querySelector('form');
const config = {
errorAttribute: 'aria-invalid',
errorClass: 'error'
};
// Helpers
const isFormInput = target => {
const { nodeName } = target;
@reecelucas
reecelucas / useNetworkConnectivity.js
Last active April 2, 2019 16:31
Simple network connectivity hook
import { useState, useEffect } from 'react';
/**
* navigator.onLine behaves a little differently across browsers
* (https://developer.mozilla.org/en-US/docs/Web/API/NavigatorOnLine/onLine#Specification).
* For bullet-proof detection you can add to this hook using some of the suggestions
* mentioned here https://www.html5rocks.com/en/mobile/workingoffthegrid/.
*
* Usage:
* const isOnline = useNetworkConnectivity();
@reecelucas
reecelucas / useClickOutside.js
Last active April 2, 2019 16:32
React hook to detect when a click happens outside of a specified element
import { useEffect } from 'react';
/**
* Usage:
* useClickOutside(myRef, event => {
* console.log(`${event.target} is outside of ${myRef.current}`);
* });
*/
export default (elemRef, fn) => {
useEffect(() => {
@reecelucas
reecelucas / details-dropdown.html
Last active April 11, 2019 16:47
Accessible dropdown menu using the `<details>` element. https://codepen.io/reecelucas/pen/QozpGw
<details class="c-menu" data-js-menu>
<summary id="menu-control" class="c-menu__control" data-js-menu-control>
Actions
</summary>
<ul id="menu" class="c-menu__list" data-js-menu-list>
<li>
<a href="#dowload">Download</a>
</li>
<li>
<a href="#copy">Copy to Clipboard</a>
@reecelucas
reecelucas / useProximity.js
Last active April 18, 2019 12:21
React hook to detect proximity to an element. https://codesandbox.io/embed/0qwjq74w0p.
import { useEffect, useState } from "react";
const useProximity = (elemRef, perimeter = 100) => {
const [withinPerimeter, setWithinPerimeter] = useState(false);
useEffect(() => {
if (!elemRef || !elemRef.current) return;
let ticking = false;
const { current } = elemRef;