CtrlK
BlogDocsLog inGet started
Tessl Logo

tessl/npm-mantine--hooks

A comprehensive collection of 75+ React hooks for state and UI management including storage, events, browser APIs, and performance optimizations

Pending
Quality

Pending

Does it follow best practices?

Impact

Pending

No eval scenarios have been run

SecuritybySnyk

Pending

The risk profile of this skill

Overview
Eval results
Files

specialized.mddocs/

Specialized

Advanced and specialized hooks for unique UI patterns including color picker integration, file dialogs, selection management, and radial interactions.

Capabilities

useEyeDropper

EyeDropper API integration for color picking from the screen.

/**
 * EyeDropper API integration for color picking
 * @returns Object with support status and open function
 */
function useEyeDropper(): UseEyeDropperReturnValue;

interface EyeDropperOpenOptions {
  signal?: AbortSignal;
}

interface EyeDropperOpenReturnType {
  sRGBHex: string;
}

interface UseEyeDropperReturnValue {
  supported: boolean;
  open: (options?: EyeDropperOpenOptions) => Promise<EyeDropperOpenReturnType>;
}

Usage Examples:

import { useEyeDropper } from "@mantine/hooks";

function ColorPicker() {
  const [color, setColor] = useState('#000000');
  const eyeDropper = useEyeDropper();
  
  const pickColor = async () => {
    if (!eyeDropper.supported) {
      alert('EyeDropper API not supported');
      return;
    }
    
    try {
      const result = await eyeDropper.open();
      setColor(result.sRGBHex);
    } catch (error) {
      console.log('Color picking cancelled');
    }
  };
  
  return (
    <div>
      <div style={{ width: 50, height: 50, background: color }} />
      <button onClick={pickColor} disabled={!eyeDropper.supported}>
        Pick Color from Screen
      </button>
    </div>
  );
}

useFileDialog

File input dialog with configurable options and callback handling.

/**
 * File input dialog with options
 * @param options - Configuration for file selection
 * @returns Object with open and reset functions
 */
function useFileDialog(options: UseFileDialogOptions): UseFileDialogReturnValue;

interface UseFileDialogOptions {
  multiple?: boolean;
  accept?: string;
  capture?: boolean | 'user' | 'environment';
  onFiles: (files: FileList | null) => void;
}

interface UseFileDialogReturnValue {
  open: () => void;
  reset: () => void;
}

Usage Examples:

import { useFileDialog } from "@mantine/hooks";

function ImageUploader() {
  const [images, setImages] = useState<File[]>([]);
  
  const fileDialog = useFileDialog({
    multiple: true,
    accept: 'image/*',
    onFiles: (files) => {
      if (files) {
        setImages(Array.from(files));
      }
    }
  });
  
  return (
    <div>
      <button onClick={fileDialog.open}>
        Select Images
      </button>
      <button onClick={fileDialog.reset}>
        Reset
      </button>
      <div>
        {images.map((file, index) => (
          <div key={index}>{file.name}</div>
        ))}
      </div>
    </div>
  );
}

// Camera capture
function CameraCapture() {
  const cameraDialog = useFileDialog({
    accept: 'image/*',
    capture: 'environment', // Use back camera
    onFiles: (files) => {
      if (files && files[0]) {
        handlePhotoCapture(files[0]);
      }
    }
  });
  
  return <button onClick={cameraDialog.open}>Take Photo</button>;
}

useSelection

Multi-select state management with comprehensive selection handlers.

/**
 * Multi-select state management
 * @param items - Array of items to manage selection for
 * @param input - Configuration for selection behavior
 * @returns Object with selected items, handlers, and utilities
 */
function useSelection<T>(
  items: T[],
  input?: UseSelectionInput<T>
): UseSelectionReturnValue<T>;

interface UseSelectionInput<T> {
  multiple?: boolean;
  value?: T | T[];
  onSelectionChange?: (value: T | T[]) => void;
}

interface UseSelectionHandlers<T> {
  select: (item: T) => void;
  deselect: (item: T) => void;
  toggle: (item: T) => void;
  selectAll: () => void;
  deselectAll: () => void;
  setSelection: (items: T[]) => void;
}

interface UseSelectionReturnValue<T> {
  selected: T[];
  handlers: UseSelectionHandlers<T>;
  isSelected: (item: T) => boolean;
}

Usage Examples:

import { useSelection } from "@mantine/hooks";

function TodoList() {
  const todos = [
    { id: 1, text: 'Learn React' },
    { id: 2, text: 'Build app' },
    { id: 3, text: 'Deploy' }
  ];
  
  const selection = useSelection(todos, {
    multiple: true,
    onSelectionChange: (selected) => {
      console.log('Selected todos:', selected);
    }
  });
  
  const deleteSelected = () => {
    // Delete selected todos
    const selectedIds = selection.selected.map(todo => todo.id);
    deleteTodos(selectedIds);
    selection.deselectAll();
  };
  
  return (
    <div>
      <div>
        <button onClick={selection.handlers.selectAll}>
          Select All
        </button>
        <button onClick={selection.handlers.deselectAll}>
          Deselect All
        </button>
        <button onClick={deleteSelected} disabled={selection.selected.length === 0}>
          Delete Selected ({selection.selected.length})
        </button>
      </div>
      
      {todos.map(todo => (
        <div key={todo.id}>
          <input
            type="checkbox"
            checked={selection.isSelected(todo)}
            onChange={() => selection.handlers.toggle(todo)}
          />
          {todo.text}
        </div>
      ))}
    </div>
  );
}

useRadialMove

Circular/radial mouse interactions for knobs, dials, and circular controls.

/**
 * Circular/radial mouse interactions
 * @param options - Configuration for radial movement
 * @returns Object with ref callback
 */
function useRadialMove<T extends HTMLElement = any>(
  options?: UseRadialMoveOptions
): UseRadialMoveReturnValue<T>;

/**
 * Normalize radial value to 0-1 range
 * @param value - Value to normalize
 * @returns Normalized value
 */
function normalizeRadialValue(value: number): number;

interface UseRadialMoveOptions {
  onValueChange?: (value: number) => void;
  onScrubStart?: () => void;
  onScrubEnd?: () => void;
  step?: number;
  max?: number;
  min?: number;
}

interface UseRadialMoveReturnValue<T extends HTMLElement = any> {
  ref: React.RefCallback<T | null>;
}

Usage Examples:

import { useRadialMove, normalizeRadialValue } from "@mantine/hooks";

function VolumeKnob() {
  const [volume, setVolume] = useState(0.5);
  
  const { ref } = useRadialMove({
    onValueChange: (value) => {
      const normalized = normalizeRadialValue(value);
      setVolume(normalized);
    },
    min: 0,
    max: 1,
    step: 0.01
  });
  
  return (
    <div
      ref={ref}
      style={{
        width: 100,
        height: 100,
        borderRadius: '50%',
        border: '2px solid #ccc',
        position: 'relative',
        cursor: 'pointer'
      }}
    >
      <div
        style={{
          position: 'absolute',
          top: '50%',
          left: '50%',
          width: 4,
          height: 40,
          background: '#000',
          transformOrigin: 'center bottom',
          transform: `translate(-50%, -100%) rotate(${volume * 270 - 135}deg)`
        }}
      />
      <div>Volume: {Math.round(volume * 100)}%</div>
    </div>
  );
}

useMouse

Track mouse position relative to an element.

/**
 * Track mouse position relative to element
 * @returns Object with ref and mouse coordinates
 */
function useMouse<T extends HTMLElement = any>(): {
  ref: React.RefCallback<T | null>;
  x: number;
  y: number;
};

useTextSelection

Track current text selection in the document.

/**
 * Track current text selection
 * @returns Current Selection object or null
 */
function useTextSelection(): Selection | null;

useFocusReturn

Return focus to previously focused element after modal/dialog closes.

/**
 * Return focus to previous element
 * @param options - Configuration for focus return
 * @returns Object with returnFocus function
 */
function useFocusReturn(options?: UseFocusReturnOptions): UseFocusReturnReturnValue;

interface UseFocusReturnOptions {
  opened: boolean;
  shouldReturnFocus?: boolean;
}

interface UseFocusReturnReturnValue {
  returnFocus: () => void;
}

useLogger

Development logging utility for debugging hook state changes.

/**
 * Development logging utility
 * @param name - Name for the logger
 * @param props - Object to log when it changes
 */
function useLogger(name: string, props: Record<string, any>): void;

Usage Examples:

import { useLogger } from "@mantine/hooks";

function DebugComponent({ userId, settings }: Props) {
  const [count, setCount] = useState(0);
  
  // Log prop and state changes in development
  useLogger('DebugComponent', { userId, settings, count });
  
  return (
    <div>
      <button onClick={() => setCount(c => c + 1)}>
        Count: {count}
      </button>
    </div>
  );
}

Specialized Patterns

Custom File Upload

import { useFileDialog, useClipboard } from "@mantine/hooks";

function AdvancedFileUploader() {
  const [files, setFiles] = useState<File[]>([]);
  const [uploadProgress, setUploadProgress] = useState<Record<string, number>>({});
  const clipboard = useClipboard();
  
  const imageDialog = useFileDialog({
    multiple: true,
    accept: 'image/*',
    onFiles: (fileList) => {
      if (fileList) {
        const newFiles = Array.from(fileList);
        setFiles(prev => [...prev, ...newFiles]);
        
        // Start upload for each file
        newFiles.forEach(uploadFile);
      }
    }
  });
  
  const uploadFile = async (file: File) => {
    const formData = new FormData();
    formData.append('file', file);
    
    try {
      const response = await fetch('/upload', {
        method: 'POST',
        body: formData
      });
      
      if (response.ok) {
        const result = await response.json();
        clipboard.copy(result.url);
      }
    } catch (error) {
      console.error('Upload failed:', error);
    }
  };
  
  return (
    <div>
      <button onClick={imageDialog.open}>
        Select Images
      </button>
      <div>
        {files.map((file, index) => (
          <div key={index}>
            {file.name}
            {uploadProgress[file.name] && (
              <div>Progress: {uploadProgress[file.name]}%</div>
            )}
          </div>
        ))}
      </div>
    </div>
  );
}

docs

browser-apis.md

device.md

dom-events.md

index.md

navigation.md

network.md

observers.md

specialized.md

state-management.md

storage.md

timing.md

utilities.md

tile.json