Skip to content

Instantly share code, notes, and snippets.

View loilo's full-sized avatar

Florian Reuschel loilo

View GitHub Profile
@loilo
loilo / pass-slots.md
Last active October 31, 2025 07:28
Vue: Pass Slots through from Parent to Child Components

Vue: Pass Slots through from Parent to Child Components

The Situation

  • We've got some components A, B and C which provide different slots.
    const A = {
      template: `<div><slot name="a">Default A Content</slot></div>`
    }

const B = {

@loilo
loilo / -alpine-select.md
Last active October 19, 2025 07:15
Select Dropdown with Alpine.js

Alpine.js x-select Directive

x-select is an Alpine.js directive which provides a styled enhancement over a native <select> element.

Its main goal is to be a progressive enhancement adding no actual features to a select dropdown apart from making it more visually appealing to use (especially for select fields with multiple).

Further goals include:

  • Accessibility: Appropriate ARIA roles are set, expected keyboard shortcuts can be used.
  • Easy stylability: Custom properties exist for the main features.
@loilo
loilo / base64.js
Last active September 10, 2025 14:27
URL-Safe LZMA Compression
/**
* Convert between Uint8Array and Base64 strings
* Allows for any encoded JS string to be converted (as opposed to atob()/btoa() which only supports latin1)
*
* Original implementation by madmurphy on MDN
* @see https://developer.mozilla.org/en-US/docs/Web/API/WindowBase64/Base64_encoding_and_decoding#Solution_1_–_JavaScript%27s_UTF-16_%3E_base64
*/
function b64ToUint6(nChr) {
return nChr > 64 && nChr < 91
@loilo
loilo / contenteditable-caret-position.js
Last active August 24, 2025 16:00
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()
range.selectNodeContents(element)
@loilo
loilo / bem.md
Last active August 20, 2025 13:15
Sass mixins for BEM

ATTENTION!

I keep this Gist for archival reasons, however I strongly recommend against using it. As I discovered after several weeks in production usage, these BEM mixins cause unexpected, unfixable and hard-to-debug selectors in some cases (especially when nested in some ways).

Sass mixins for BEM

This is a utility with three simple Sass mixins for writing BEM as DRY as possible, heavily inspired by Hugo Giraudel's article on CSS Tricks.

It exposes three Sass mixins: block, element and modifier.

/**
* Export all data from an IndexedDB database
*
* @param {IDBDatabase} idbDatabase The database to export from
* @return {Promise<string>}
*/
export function exportToJson(idbDatabase) {
return new Promise((resolve, reject) => {
const exportObject = {}
if (idbDatabase.objectStoreNames.length === 0) {
@loilo
loilo / ResponsiveContainer.md
Last active July 4, 2025 09:48
A Container-Query-like Responsive Container in Vue.js

Vue Responsive Container

A container component reacting to breakpoints on its own width or height, powered by ResizeObserver and scoped slots.

It is similar to things like vue-resize in that you can use it to observe a component's size. However the ResponsiveContainer will not emit any events, its whole point is to work as declaratively as possible, taking a predefined set of breakpoints you can access in your component.

Basic Usage

@loilo
loilo / split-pull-requests.md
Last active June 18, 2025 12:15
Split a large pull request into two
@loilo
loilo / get-local-iso-string.js
Last active May 23, 2025 10:50
ISO 8601 date string – like Date.prototype.toISOString(), but with local timezone offset
function getLocalISOString(date) {
const offset = date.getTimezoneOffset()
const offsetAbs = Math.abs(offset)
const isoString = new Date(date.getTime() - offset * 60 * 1000).toISOString()
return `${isoString.slice(0, -1)}${offset > 0 ? '-' : '+'}${String(Math.floor(offsetAbs / 60)).padStart(2, '0')}:${String(offsetAbs % 60).padStart(2, '0')}`
}
@loilo
loilo / readme.md
Last active May 9, 2025 22:23
Sass Dark/Light Theme Mixin

Sass Dark/Light Theme Mixin

This is a Sass mixin to handle a 3-way dark mode. It relies on a data-theme attribute on your <html> element with a value of light or dark. If data-theme is absent (i.e. it's neither light nor dark), the system's preferred mode is used.

body {
  // matches data-theme="light" or data-theme="auto" with system instructing light mode
  @include light {
    background: white;
 color: black;