Skip to content

Instantly share code, notes, and snippets.

import * as React from "react";
import { useMousePosition } from "~/hooks/useMousePosition";
/** Component to cover the area between the mouse cursor and the sub-menu, to allow moving cursor to lower parts of sub-menu without the sub-menu disappearing. */
export function MouseSafeArea(props: { parentRef: React.RefObject<HTMLDivElement> }) {
const { x = 0, y = 0, height: h = 0, width: w = 0 } = props.parentRef.current?.getBoundingClientRect() || {};
const [mouseX, mouseY] = useMousePosition();
const positions = { x, y, h, w, mouseX, mouseY };
return (
<div
@ggallon
ggallon / useMousePosition.ts
Created March 5, 2023 02:22 — forked from eldh/useMousePosition.ts
useMousePosition
import * as React from "react";
import { throttle } from "lodash";
/**
* Mouse position as a tuple of [x, y]
*/
type MousePosition = [number, number];
/**
* Hook to get the current mouse position
@ggallon
ggallon / The Rules.md
Created November 7, 2022 12:54 — forked from sebmarkbage/The Rules.md
The Rules of React

The Rules of React

All libraries have subtle rules that you have to follow for them to work well. Often these are implied and undocumented rules that you have to learn as you go. This is an attempt to document the rules of React renders. Ideally a type system could enforce it.

What Functions Are "Pure"?

A number of methods in React are assumed to be "pure".

On classes that's the constructor, getDerivedStateFromProps, shouldComponentUpdate and render.

Scaling your API with rate limiters

The following are examples of the four types rate limiters discussed in the accompanying blog post. In the examples below I've used pseudocode-like Ruby, so if you're unfamiliar with Ruby you should be able to easily translate this approach to other languages. Complete examples in Ruby are also provided later in this gist.

In most cases you'll want all these examples to be classes, but I've used simple functions here to keep the code samples brief.

Request rate limiter

This uses a basic token bucket algorithm and relies on the fact that Redis scripts execute atomically. No other operations can run between fetching the count and writing the new count.

// Simplistic (probably most common) approach.
// This approach assumes either that:
// 1) passive effects are always run synchronously, after paint, or
// 2) passive effects never attach handlers for bubbling events
// If both of the above are wrong (as can be the case) then problems might occur!
useEffect(() => {
const handleDocumentClick = (event: MouseEvent) => {
// It's possible that a "click" event rendered the component with this effect,
// in which case this event handler might be called for the same event (as it bubbles).
// In most scenarios, this is not desirable.
@ggallon
ggallon / server.js
Created May 18, 2017 09:17
Meteor Edit html tag
/***********************************************************************
* Meteor the (undocumented) addHtmlAttributeHook in the webapp package
***********************************************************************/
import { Meteor } from 'meteor/meteor';
import { WebApp } from 'meteor/webapp';
if (Meteor.isServer) {
Meteor.startup(function () {
WebApp.addHtmlAttributeHook(function() {