Skip to content

Instantly share code, notes, and snippets.

Avatar

James Doyle james2doyle

View GitHub Profile
@james2doyle
james2doyle / lodash.memo.ttl.ts
Last active Mar 5, 2021
Use lodash memoize with a TTL. Allows calls to be cached by time as well as argument values
View lodash.memo.ttl.ts
import { memoize, partialRight } from 'lodash';
/**
* Custom memoize that uses a 1 minute TTL
* @see https://lodash.com/docs/4.17.15#memoize
*/
const memo = partialRight(memoize, function memoResolver(...args) {
// or for one hour: (new Date()).getHours();
const time = (new Date()).getMinutes();
@james2doyle
james2doyle / DynamicIcon.vue
Last active Feb 11, 2021
Load an icon dynamically in Vue 3 using the import keyword and a ref
View DynamicIcon.vue
<!--
Icon Component
Usage:
<icon icon="button"></icon>
-->
<template>
<transition name="fade" mode="out-in">
<div v-if="!loadedIcon" class="w-4">&nbsp;</div>
<component :is="loadedIcon" v-else v-once class="icon-wrapper" :name="icon" v-bind="$attrs" v-on="$listeners" />
@james2doyle
james2doyle / make-uuid.ts
Created Jan 20, 2021
Create a UUID using window.performance or Date.now
View make-uuid.ts
/**
* Create a UUID
* @see http://stackoverflow.com/a/8809472/188246
*
* @return {string}
*/
export default function makeUuid(): string {
// your favourite guid generation function could go here
// ex: http://stackoverflow.com/a/8809472/188246
let d = new Date().getTime() + (window.performance || Date).now();
@james2doyle
james2doyle / i18n.lodash.ts
Created Jan 7, 2021
An incredibly simple i18n translation function using lodash `get` and `template` functions
View i18n.lodash.ts
import { get, template } from 'lodash';
const en = require('@/lang/en.json');
/**
* Translate a string from a preloaded JSON document
*/
const intl = function(key: string, values: Record<string, string | number> = {}): string {
const compiled = template(get(en, key), {
interpolate: /{([\s\S]+?)}/g, // {myVar}
});
@james2doyle
james2doyle / gentle-flex.css
Created Dec 18, 2020
Gentle Flex is a truer centering-only strategy. As gently as possible, all items are * stacked, centered, and spaced
View gentle-flex.css
/*
* Gentle Flex is a truer centering-only strategy. It's soft and gentle,
* because unlike `place-content: center`, no children's box sizes are
* changed during the centering. As gently as possible, all items are
* stacked, centered, and spaced.
*
* @see https://web.dev/centering-in-css/#2.-gentle-flex
*/
.gentle-flex {
display: flex;
@james2doyle
james2doyle / dynamic-import-component-setup-vue-3.vue
Created Dec 15, 2020
Usage of a dynamically imported component that comes from a prop in Vue 3
View dynamic-import-component-setup-vue-3.vue
<template>
<button type="button">
<div v-if="!button">&nbsp;</div>
<!-- the `is` prop can take a full on component! -->
<component :is="button" v-else />
</button>
</template>
<script>
import { defineComponent, ref } from '@vue/composition-api';
@james2doyle
james2doyle / fastmod-webpack-dynamic-import-chunk.sh
Last active Dec 3, 2020
A fastmod snippet that refactors module imports to dynamic imports with wepback chunking enabled
View fastmod-webpack-dynamic-import-chunk.sh
# https://github.com/facebookincubator/fastmod
# old code: `import MyComponent from 'Components/MyComponent.vue';`
# new code: `const MyComponent = () => import(/* webpackChunkName: "MyComponent" */ 'Components/MyComponent.vue');`
# note: you may need to reorder your imports when using a dynamic import
fastmod -m -d ./ --extensions vue \
'import (.*?) from \'(.*?)\';' \
'const ${1} = () => import(/* webpackChunkName: "${1}" */ \'${2}\');'
@james2doyle
james2doyle / historyTracker.js
Last active Dec 1, 2020
Track an object as an array of historical states and move forwards and backwards in time. Tracker function uses an internal array. Has helpful methods for undo, redo, reset, push, and fetching the current item
View historyTracker.js
/**
* Track an array as a history and move forwards and backwards in time
*
* @param {string} name = 'history'
*
* @returns {{ name, index, active, state, skipNextPush, current, undo, redo, undoReady, redoReady, sync, reset, push }}
*/
const historyTracker = function(name = 'history') {
return {
name,
@james2doyle
james2doyle / vue-async-component.js
Last active Dec 4, 2020
An example of how to use async data within a Vue component
View vue-async-component.js
/**
* We need to use a plain JS (or TS) file in order to handle all the async
* code we are going to handle
* we also need to follow the Async Component Guide:
* @see https://vuejs.org/v2/guide/components-dynamic-async.html#Handling-Loading-State
*/
// some API call, async task, or delayed function
const myAsyncFunction = () =>
new Promise((resolve) => {
@james2doyle
james2doyle / hyperactiv-use-state-usage.js
Last active Dec 2, 2020
Use hyperactiv to recreate hooks with Javascript Proxy objects. Supports Redux devtool
View hyperactiv-use-state-usage.js
import setState from 'use-state.js';
const [state, onStateUpdated] = useState('my-state', { count: 1 });
console.log(state.count); // logs: "1"
// runs on init in order to compute dependencies
onStateUpdated((/* newState, originalState */) => {
console.log('stateUpdated', state.count); // logs: "stateUpdated 1"
});