Skip to content

Instantly share code, notes, and snippets.

View doubleedesign's full-sized avatar

Leesa Ward doubleedesign

View GitHub Profile
doubleedesign / markup.php
Created September 23, 2023 11:45
Alter output of WordPress TinyMCE field content
View markup.php
* Add spans and icons to buttons added by applying custom link classes in the WYSIWYG editor
* @param $content
* @return string
function wapr_add_icons_to_buttons($content): string {
return preg_replace_callback('/<a class="btn btn--(?:.*) btn--icon" href="(?:.*)">(.*)<\/a>/', function($match) {
return str_replace($match[1], '<span>'.$match[1].'</span><i class="fa-regular fa-chevron-right"></i>', $match[0]);
}, $content);
doubleedesign / useTruncatedText.ts
Last active August 7, 2023 01:27
React hook to keep text on one line, truncating it with an ellpisis if it's longer than its container's width. Demo:
View useTruncatedText.ts
import { useState, useEffect, useMemo, MutableRefObject } from 'react';
import { useVisibleSize } from './useVisibleSize.ts';
export function useTruncatedText(outerRef: MutableRefObject<any>, innerRef: MutableRefObject<any>) {
const { width: outerWidth } = useVisibleSize(outerRef.current);
const { width: innerWidth } = useVisibleSize(innerRef.current);
useEffect(() => {
if (innerRef.current) { = "nowrap";
doubleedesign / ThemeUtils.ts
Last active April 7, 2023 01:33
Shortcut function for choosing text colour based on background colour using Styled Components + Polished
View ThemeUtils.ts
import { meetsContrastGuidelines } from 'polished';
import { ContrastScores } from 'polished/lib/types/color';
type WCAGLevel = keyof ContrastScores;
export function contrastTextColour(color: string, wcag: WCAGLevel = 'AA') {
const scores = meetsContrastGuidelines(color, '#fff');
if(scores[wcag]) {
return '#fff';
doubleedesign / ColorThemeTypedExample.styled.ts
Last active April 7, 2023 01:34
Typing styled-components props: Valid string values according to what's available in theme
View ColorThemeTypedExample.styled.ts
import styled from 'styled-components';
import { ThemeColor } from '../../types';
interface ButtonProps {
color: ThemeColor
export const StyledButton = styled.button<ButtonProps>`
background: ${({ theme, color }): string => theme.colors[color]};
// more styles
doubleedesign / Button.styled.ts
Created April 7, 2023 00:10
Extend a styled component as a different HTML element
View Button.styled.ts
import styled from 'styled-components';
interface ButtonProps {
// Props to be used for styling below
export const StyledButton = styled.button<ButtonProps>`
// Styles
&:hover, &:focus, &:active {
doubleedesign / useLocalStorage.ts
Created March 21, 2023 11:25
useLocalStorage React hook. Keep a state value in sync with one cached in the browser using local storage.
View useLocalStorage.ts
import { useState, useEffect, Dispatch, SetStateAction } from 'react';
export function useLocalStorage<T>(key: string, defaultValue: T): { value: T; setValue: Dispatch<SetStateAction<T>> } {
const [value, setValue] = useState(() => {
return localStorage?.getItem(key) ? JSON.parse(localStorage.getItem(key)) : defaultValue;
useEffect(() => {
localStorage.setItem(key, JSON.stringify(value));
}, [key, value]);
doubleedesign / _useResize.ts
Last active March 31, 2023 02:20
useResize React hook. Dynamically get height and width of an element when its size changes and store the values in state. Demo:
View _useResize.ts
import { MutableRefObject, useMemo, useEffect, useState } from 'react';
interface Dimensions {
width: number;
height: number;
export function useResize(ref: MutableRefObject<HTMLElement | undefined>, deps: unknown[]): Dimensions {
const [width, setWidth] = useState<number>(0);
const [height, setHeight] = useState<number>(0);
doubleedesign / _box.scss
Last active March 19, 2023 10:27
Vertically centred CSS arrow/triangle on side of box. Demo:
View _box.scss
$spacing: (
xs: 0.25rem,
sm: 0.5rem,
md: 0.75rem,
lg: 1rem,
xl: 1.5rem,
xxl: 2rem
$colours: (
doubleedesign / typechecker.test.ts
Last active February 5, 2023 11:30
Function to determine the TypeScript type of a given value using a predefined list of types
View typechecker.test.ts
import savedArtists from '../json-data/test/artists.json' assert { type: 'json'};
import { getType } from './typechecker';
// NOTE: These tests are a work in progress,
as I have so far only completed work with the "Artist" type on the project at the time of writing
describe('Typechecker', () => {
it('Correctly identifies and Artist', () => {
const item = savedArtists[0];
const type = getType(item);
doubleedesign / class-unhooky-plugin-custom-admin-stuff.php
Last active March 21, 2023 11:26
Unhook a Ninja Forms plugin action from within another plugin. The context for this example was using Ninja Forms for Expression of Interest forms associated with Jobs (a custom post type), and a customised admin screen for viewing submissions. (This isn't the whole plugin, it's just the parts required to show how to unhook a Ninja Forms functio…
View class-unhooky-plugin-custom-admin-stuff.php
* Job listings functionality for Client Website
* Note: Requires Ninja Forms plugin
* Note: Truncated for use in a gist to demonstrate unhooking a Ninja Forms function
* @since 1.0.0
* @package MyPlugin
* @subpackage MyPlugin/admin
class MyPlugin_Jobs extends MyPlugin_Settings {