|
| 1 | +# CLAUDE.md |
| 2 | + |
| 3 | +This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository. |
| 4 | + |
| 5 | +## Project Overview |
| 6 | + |
| 7 | +This is **react-float-menu**, a smart draggable floating menu component for React. It's a library distributed via npm that provides a configurable floating menu with features like edge detection, auto-flipping, keyboard navigation, and theme customization. |
| 8 | + |
| 9 | +## Development Commands |
| 10 | + |
| 11 | +### Building |
| 12 | +- **Build library**: `pnpm build` - Builds the library using Vite in production mode with multiple formats (ESM, CJS, UMD), type declarations, and source maps |
| 13 | +- **Type check**: `pnpm typecheck` - Run TypeScript type checking without emitting files |
| 14 | + |
| 15 | +### Development Server |
| 16 | +- `pnpm dev` - Start Vite development server with hot module replacement for testing the component |
| 17 | + |
| 18 | +### Testing |
| 19 | +- **Run all tests**: `pnpm test` - Runs all Vitest tests once |
| 20 | +- **Test in watch mode**: `pnpm test:dev` - Runs tests in watch mode with silent output |
| 21 | +- **Coverage report**: `pnpm test:coverage` - Generates test coverage report with HTML, LCOV, and text output |
| 22 | +- **E2E tests**: `pnpm cypress:open` - Opens Cypress for interactive E2E testing |
| 23 | +- **E2E headless**: `pnpm cypress:quiet` - Runs Cypress tests headless in Chrome |
| 24 | + |
| 25 | +Note: Test files are located at `src/**/*test.tsx` and use Vitest (v2) with jsdom environment. |
| 26 | + |
| 27 | +### Linting & Formatting |
| 28 | +- **Lint JS**: `pnpm lint:js` - Lint TypeScript/TSX files with ESLint v9 (flat config) |
| 29 | +- **Fix JS**: `pnpm lint:js-fix` - Auto-fix linting issues |
| 30 | +- **Lint CSS**: `pnpm lint:css` - Lint SCSS files with Stylelint v16 |
| 31 | +- **Fix CSS**: `pnpm lint:css-fix` - Auto-fix SCSS linting issues |
| 32 | +- **Lint all**: `pnpm lint:all` - Run both JS and CSS linting |
| 33 | +- **Format**: `pnpm format` - Format code using Prettier v3 |
| 34 | + |
| 35 | +## Architecture |
| 36 | + |
| 37 | +### Entry Point |
| 38 | +- `src/react-float-menu.ts` - Main library export that exports the `Menu` component (alias for `MenuHead`) |
| 39 | + |
| 40 | +### Core Components |
| 41 | +- **MenuHead** (`src/components/main/index.tsx`) - The main floating menu button component that orchestrates all functionality |
| 42 | + - Manages state for menu open/close, position, drag state |
| 43 | + - Handles menu positioning logic including edge detection and auto-flipping |
| 44 | + - Provides MenuContext to child components |
| 45 | +- **MenuContainer** (`src/components/menu-container/menu-container.tsx`) - Container for the actual menu content |
| 46 | +- **MenuItem** (`src/components/menu-list-item/menu-list-item.tsx`) - Individual menu items with submenu support |
| 47 | +- **Context** (`src/components/context.ts`) - React Context providing menu configuration to all child components |
| 48 | + |
| 49 | +### Custom Hooks (src/effects/) |
| 50 | +The component uses several custom hooks for modular functionality: |
| 51 | +- **usePosition** - Handles dragging, positioning, and pointer events for the floating button |
| 52 | +- **useMenuHidden** - Detects when menu is hidden beyond screen edges |
| 53 | +- **useKeyboardNav** - Implements keyboard navigation within menus |
| 54 | +- **useCloseOnClick** - Closes menu when clicking outside |
| 55 | +- **useCloseOnEscape** - Closes menu on Escape key |
| 56 | +- **useMenuToFront** - Brings menu to focus when near screen edges |
| 57 | + |
| 58 | +### Menu Item Model |
| 59 | +Menu items support hierarchical structure with `children` for submenus. Each item has: |
| 60 | +- `name` - Label text |
| 61 | +- `id` - Unique identifier (auto-generated if not provided) |
| 62 | +- `children` - Array of menu items for submenu |
| 63 | +- `icon` - Optional icon component |
| 64 | +- `selected` - Internal state for selected item |
| 65 | + |
| 66 | +### Build Configuration |
| 67 | +- **Vite** (`vite.config.ts`) - Primary build tool for both development and library distribution |
| 68 | + - Entry: `src/react-float-menu.ts` |
| 69 | + - Output formats: ESM (`react-float-menu.esm.js`), CJS (`react-float-menu.cjs`), UMD (`react-float-menu.umd.js`) |
| 70 | + - Type declarations: Generated automatically with `vite-plugin-dts` → `dist/index.d.ts` |
| 71 | + - Externals: React/ReactDOM are peer dependencies (not bundled) |
| 72 | + - Development: Uses SWC compiler (@vitejs/plugin-react-swc) for fast transpilation and HMR |
| 73 | + - Production: Minification with Terser, source maps enabled, CSS code-split |
| 74 | + - Package exports configured for proper ESM/CJS resolution |
| 75 | +- **PostCSS** (`postcss.config.js`) - Modern plugin stack |
| 76 | + - postcss-preset-env (stage 2) - Modern CSS syntax support |
| 77 | + - autoprefixer - Vendor prefixing |
| 78 | + - cssnano (production only) - CSS minification |
| 79 | +- **Vitest** (`vitest.config.ts`) - Test runner with jsdom environment |
| 80 | +- **ESLint** (`eslint.config.js`) - Flat config format (v9) for JS/TS linting |
| 81 | +- **Stylelint** - SCSS linting with modern standards config (v16) |
| 82 | + |
| 83 | +### Styling |
| 84 | +- Uses SCSS modules for component styling with CSS Modules features |
| 85 | +- CSS variables for theming (primary color, dimensions, width) |
| 86 | +- Modern CSS syntax (nesting, custom properties) via PostCSS |
| 87 | +- Dart Sass compiler (v1.81+) for fast SCSS processing |
| 88 | + |
| 89 | +## Key Features Implementation |
| 90 | + |
| 91 | +### Auto-flip Menu |
| 92 | +The menu automatically flips vertically when near the bottom of the screen (controlled by `autoFlipMenu` prop and `shouldFlipVertical` logic in MenuHead). |
| 93 | + |
| 94 | +### Edge Detection |
| 95 | +The `useMenuHidden` hook and related logic in MenuHead detect when the menu button is near screen edges and adjusts menu positioning accordingly (`bringMenuToFocus` prop). |
| 96 | + |
| 97 | +### Draggable Button |
| 98 | +The `usePosition` hook implements dragging using pointer events (not when `pin` prop is set). |
| 99 | + |
| 100 | +### Theme Customization |
| 101 | +Theme is merged with default theme (`src/utils/theme-default.ts`) and provided via context. CSS variables are set on the menu head element. |
0 commit comments