This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| // Subscribes to `scroll` (passive) and exposes whether the user is moving | |
| // down the page, up, or still in the “top” band (y === 0 or within ~40px while settling). | |
| import { useEffect, useState } from 'react'; | |
| export enum ScrollDirection { | |
| Top = -1, | |
| Initial = 0, | |
| Bottom = 1, | |
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| // After mount, collects linked headings (`a > h2`–`h6`) into `{ id, text }` pairs | |
| // from the parent anchors `id`; state updates only when there are at least two (for TOC-style UI). | |
| import React from 'react'; | |
| export interface HeadingAnchor { | |
| id: string; | |
| text: string; | |
| } | |
| export const useHeadingAnchors = () => { |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| // Keeps React state in sync with `window.location.hash` (fragment without `#`) | |
| // via `hashchange`, and seeds from the initial hash on mount. | |
| import React from 'react'; | |
| export function useHashChange() { | |
| const [activeItemId, setActiveItemId] = React.useState<string | null>(null); | |
| React.useEffect(() => { | |
| if (!activeItemId && window.location.hash) { | |
| setActiveItemId(window.location.hash.substring(1)); |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| // When `open` is true, sets `document.body.style.overflow` to `hidden` so | |
| // the page behind modals/drawers does not scroll; restores `unset` when closed. | |
| import { useEffect } from 'react'; | |
| export const useDisableBodyScroll = (open: boolean) => { | |
| useEffect(() => { | |
| if (open) { | |
| document.body.style.overflow = 'hidden'; | |
| } else { | |
| document.body.style.overflow = 'unset'; |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| // Builds Theme UI `sx` transforms so a sticky/floating bar slides in on scroll-up or near the top | |
| // and slides away on scroll-down; optional burger-menu attrs keep it visible while the menu is open. | |
| import React from 'react'; | |
| import { BoxProps } from 'theme-ui'; | |
| import { useScrollDirection, ScrollDirection } from '@/hooks/useScrollDirection'; | |
| const SCROLL_Y_OFFSET_PX = 500; | |
| interface DirectionTransformProps { |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| // On non-touch devices, adds a custom dual-layer cursor (ring + lagging dot with difference blend) | |
| // that grows over links, buttons, and form controls. | |
| import React from 'react'; | |
| export function useCursorEffect() { | |
| React.useEffect(() => { | |
| const isMobileDevice = () => { | |
| return ( | |
| window.matchMedia('(pointer: coarse)').matches || /Mobi|Android/i.test(navigator.userAgent) | |
| ); |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| // On copy, rewrites clipboard text to append a random copyright line from the list (skips URLs, IP:port, and selections inside code/inputs). | |
| import React from 'react'; | |
| import sample from 'lodash/sample'; | |
| const IP_ADDR_PORT_REGEX = /^(\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}:\d{1,5})$/; | |
| const URL_REGEX = | |
| /(http(s)?:\/\/.)?(www\.)?[-a-zA-Z0-9@:%._\+~#=]{2,256}\.[a-z]{2,6}\b([-a-zA-Z0-9@:%_\+.~#?&//=]*)/g; | |
| const isURL = (str: string) => URL_REGEX.test(str); |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| // Calls the given handler when the user presses Escape (keydown on document.body). Handy for closing modals, menus, and overlays. | |
| import { useEffect } from 'react'; | |
| export const useCallbackOnEscape = (handleClose?: () => void) => { | |
| useEffect(() => { | |
| if (typeof handleClose === 'function') { | |
| const closeOnEscapeKey = (e: KeyboardEvent) => (e.key === 'Escape' ? handleClose() : null); | |
| document.body.addEventListener('keydown', closeOnEscapeKey); | |
| return () => { | |
| document.body.removeEventListener('keydown', closeOnEscapeKey); |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| // Tracks which heading (by id) is most visible in the viewport via IntersectionObserver. | |
| import { useEffect, useRef, useState } from 'react'; | |
| interface UseIntersectionOptions { | |
| root?: HTMLElement | null; | |
| rootMargin?: string; | |
| threshold?: number | number[]; | |
| } | |
| export const useActiveAnchor = (ids: string[], options: UseIntersectionOptions = {}) => { |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| 1) Open TortoiseGit -> Settings -> Network | |
| 2) SSH Client -> change to "C:\Program Files\Git\usr\bin\ssh.exe" instead of "TortoiseGitPlink.exe" |
NewerOlder