Skip to content

Instantly share code, notes, and snippets.

View loilo's full-sized avatar

Florian Reuschel loilo

View GitHub Profile
loilo /
Last active August 27, 2023 09:32
Draftlog with Vue Reactivity

Draftlog with Vue Reactivity

Draftlog is a great tool for creating rich terminal logging experiences. However, using it feels kind of imperative when coming from a data-driven frontend world (insofar as you have to decide on your own when to re-apply data and call the draft function again).

This little code snippet marries Draftlog with the @vue/reactivity (one of the earlier implementation of the signals pattern in the web development world).

You basically keep using console.draft() just as before, but you can pass it reactive data which will cause the draft to update automatically when that data changes.

loilo / plugin-extract-remote-assets.js
Created October 3, 2022 12:13
Extract Remote Assets Rollup Plugin
import { createFilter } from '@rollup/pluginutils'
import got from 'got'
import MagicString from 'magic-string'
import path from 'node:path'
import revisionHash from 'rev-hash'
function escapeRegex(string) {
return string.replace(/[.*+?^${}()|[\]\\]/g, '\\$&')
loilo /
Created August 18, 2022 16:25
Simple .zip file generation with JavaScript using JSZip

Simple .zip file generation with JavaScript using JSZip

The zipTree function exported from this module takes a file tree object and creates a zip object from it using JSZip (which you need to install first via npm install jszip):

// A tree is just a collection of file names mapped to their contents
let data = {
  // Use a string for text content
  'file.txt': '...file content...',
loilo /
Created August 16, 2022 18:29
This license applies to all of loilo's public GitHub Gists (unless otherwise specified or not eligible for copyright)
loilo / xpath.js
Last active November 27, 2022 11:07
Find DOM nodes via XPath
* Find nodes via XPath
* @param {string} query
* @param {Node} root
* @returns {Node[]}
export function xpath(query, root = document) {
let iterator = document.evaluate(query, document)
loilo / use-element-breakpoints.ts
Created April 28, 2022 07:46
useElementBreakpoints – Vue Composable for Element breakpoints
// useElementBreakpoints is a Vue 3 composable that matches an element's width (or height) against a set of predefined breakpoints
// It needs @vueuse/core to be installed and uses an equivalent breakpoints input as well as an equivalent returned API
import { computed, Ref } from 'vue'
import { useElementSize, MaybeElementRef } from '@vueuse/core'
export type Breakpoints<K extends string = string> = Record<K, number>
export type ElementBreakpointsOptions = { dimension: 'width' | 'height' }
loilo / use-query-selector.js
Last active March 13, 2024 20:50
Vue useQuerySelector composable
import { readonly, ref, watch } from 'vue'
import { useMutationObserver } from '@vueuse/core'
export function useQuerySelector(selector, { root = document } = {}) {
selector = ref(selector)
root = ref(root)
const result = ref(null)
// Find first matching element inside a root element
loilo / serialize-console-log.js
Last active July 29, 2021 08:35
Serialize console.log() arguments into a string
function serializeConsoleLog(...args) {
let result = []
// Format if first argument is a string
if (typeof args[0] === 'string') {
let formattedMessage = args.shift().replace(/%[csdifoO]/g, (match) => {
// Keep raw token if no substitution args left
if (args.length === 0) return match
switch (match) {
loilo / shorten-path.ps1
Created July 15, 2021 10:34
Shorten a path in PowerShell Core 7+
# Shorten a path in PowerShell by omitting segments from the beginning.
# Parameter defaults are designed to be used in a prompt.
# Requires at least PowerShell Core 7.
function shorten-path {
Shortens a path from the end.
loilo / contenteditable-caret-position.js
Last active January 27, 2024 14:13
JavaScript Contenteditable Caret Position Utilities
// Some utilities for detecting the caret position inside a contenteditable element
* Get the number of characters in an element
* @param {Element} element
* @return {number}
function getTextLength(element) {
let range = element.ownerDocument.createRange()