Skip to content

Instantly share code, notes, and snippets.

View iffa's full-sized avatar
☀️
Sun is shining and so are you

Santeri Elo iffa

☀️
Sun is shining and so are you
View GitHub Profile
@iffa
iffa / html-lang-provider.tsx
Created September 1, 2022 07:25
Utility component for keeping the "lang" attribute of the document up to date with current user locale (Next.js/React)
import { useLocale } from "next-intl";
import { useEffect } from "react";
/**
* Utility component for keeping the lang-attribute of the document up to date.
* For Next.js, include this in e.g. custom App component.
*/
export const HtmlLangProvider = () => {
// Using next-intl here but realistically can be anything
const locale = useLocale();
{
"xo": {
"extends": "xo-react",
"prettier": true,
"space": true,
"rules": {
"import/extensions": [
2,
{
"js": "never",
@iffa
iffa / cypress-visit-with-matcher.ts
Created March 3, 2022 09:06
Custom Cypress command for visiting a page with custom media matcher stubs & locale support
export interface MatcherOptions {
darkMode: boolean;
prefersReducedMotion?: boolean;
overrideLocale?: string;
}
declare global {
namespace Cypress {
interface Chainable {
/**
@iffa
iffa / useUnauthenticatedRedirect.tsx
Created September 10, 2021 12:05
Hook for redirecting when user is not logged in (React Router v6)
import { useNavigate } from "react-router-dom";
import useAuth from "./AuthContext";
import React, { useEffect } from "react";
/**
* Redirects user to another page if not authenticated.
* @param redirectTo Path to redirect to
*/
export function useUnauthenticatedRedirect(redirectTo: string = "/") {
const navigate = useNavigate();
@iffa
iffa / ax201-hostapd.conf
Created June 1, 2021 10:29
hostapd config for Intel WiFi6 AX201 (5Ghz)
# Config for Intel WiFi6 AX201
ctrl_interface=/var/run/hostapd
ctrl_interface_group=0
logger_syslog=-1
logger_syslog_level=2
logger_stdout=-1
logger_stdout_level=1
ssid=AwesomeWifi
@iffa
iffa / filterDistinct.ts
Last active April 16, 2021 13:11
TypeScript function that takes an array of any type (object or primitive) and filters it distinctively, returning an array of unique values.
/**
* Takes an array of any type (object or primitive) and filters it distinctively.
* Duplicate values are removed, determined by the compare function.
*
* @param array Array to filter
* @param compare Compare function to compare objects for equality
* @returns Filtered array with distinct values
*/
export function filterDistinct<T>(
array: T[],
@iffa
iffa / MotionBox.tsx
Last active January 11, 2022 16:25
Extended Chakra UI Flex-component with support for Framer Motion animations. (with TypeScript typings!)
export type MotionBoxProps = Omit<FlexProps, keyof MotionProps> &
MotionProps & {
as?: React.ElementType;
};
export const MotionBox = motion.custom(
forwardRef<MotionBoxProps, 'div'>((props, ref) => {
const chakraProps = Object.fromEntries(
// do not pass framer props to DOM element
Object.entries(props).filter(([key]) => !isValidMotionProp(key))
@iffa
iffa / osrm-backend.json
Last active May 10, 2020 11:37
CapRover template for the OSRM backend
{
"captainVersion": "2",
"documentation": "https://hub.docker.com/r/peterevans/osrm-backend/",
"displayName": "Open Source Routing Machine",
"description": "The Open Source Routing Machine in a box! This is the routing engine backend.",
"dockerCompose": {
"version": "3.3",
"services": {
"$$cap_appname": {
"image": "peterevans/osrm-backend:$$cap_osrm_version",
@iffa
iffa / postgis.json
Last active December 30, 2022 06:06
CapRover template for PostGIS
{
"captainVersion": "2",
"documentation": "https://hub.docker.com/r/postgis/postgis",
"displayName": "Postgres with PostGIS",
"description": "PostGIS is a spatial database extender for PostgreSQL object-relational database.",
"dockerCompose": {
"version": "3.3",
"services": {
"$$cap_appname-db": {
"image": "postgis/postgis:$$cap_postgres_version",
@iffa
iffa / better-scroll-restoration-logic-angular.ts
Last active August 21, 2023 11:05
Custom scroll position restoration logic for Angular 2+, that doesn't consider query parameter changes in route as forward navigation, thus preventing certain scenarios where you don't want query parameter changes to scroll-to-top as they would with 'scrollPositionRestoration: enabled'.
export class AppModule {
constructor(private router: Router, private viewportScroller: ViewportScroller) {
// Disable automatic scroll restoration to avoid race conditions
this.viewportScroller.setHistoryScrollRestoration('manual');
this.handleScrollOnNavigation();
}
/**
* When route is changed, Angular interprets a simple query params change as "forward navigation" too.