npm package: @gilak/skills-globe
Description: A reusable 3D skills globe component with interactive legend
Author: Gilak
Latest version: 1.0.0

# @gilak/skills-globe

A reusable 3D skills globe component with interactive legend for React applications.

## Features

- 🎯 Interactive 3D globe with skill points
- 📱 Responsive design with breakpoint-based configurations
- 🎨 Customizable styling with CSS modules
- 🔄 Shared state management between globe and legend
- ♿ Accessibility features
- 🎭 Smooth animations and transitions

## Installation

```bash
npm install @gilak/skills-globe
```

## Peer Dependencies

This package requires the following peer dependencies:

- `react` (^18.0.0 || ^19.0.0)
- `react-dom` (^18.0.0 || ^19.0.0)
- `@react-three/fiber` (^8.0.0)
- `@react-three/drei` (^9.0.0)
- `three` (^0.160.0)
- `react-i18next` (^14.0.0)
- `i18next` (^23.0.0)

## Usage

### Basic Usage

```tsx
import { SkillsGlobe } from "@gilak/skills-globe";
import React from "react";

const skills = [
  {
    id: "typescript",
    scale: 10,
    color: "#3178C6",
  },
  {
    id: "react",
    scale: 9,
    color: "#61DAFB",
  },
  // ... more skills
];

function App() {
  const handleSkillSelect = (skillId: string) => {
    console.log(`Selected skill: ${skillId}`);
  };

  return <SkillsGlobe skills={skills} onSkillSelect={handleSkillSelect} />;
}
```

### Advanced Usage with Custom Styling

```tsx
import {
  SkillsGlobe,
  SkillsProvider,
  useSkillsContext,
} from "@gilak/skills-globe";
import React from "react";

const CustomSkillsGlobe = () => {
  return (
    <SkillsProvider skills={skills}>
      <div className="custom-container">
        <SkillsGlobe
          skills={skills}
          onSkillSelect={handleSkillSelect}
          className="custom-globe"
          style={{ height: "500px" }}
        />
      </div>
    </SkillsProvider>
  );
};
```

### Individual Components

You can also use the components individually:

```tsx
import { Globe, Legend, SkillsProvider } from "@gilak/skills-globe";
import React from "react";

function CustomLayout() {
  return (
    <SkillsProvider skills={skills}>
      <div className="layout">
        <div className="globe-section">
          <Globe skills={skills} onSkillSelect={handleSkillSelect} />
        </div>
        <div className="legend-section">
          <Legend skills={skills} onSkillSelect={handleSkillSelect} />
        </div>
      </div>
    </SkillsProvider>
  );
}
```

## API Reference

### SkillsGlobe

The main component that combines the 3D globe and legend with shared state.

#### Props

- `skills: Skill[]` - Array of skill objects
- `onSkillSelect?: (skillId: string) => void` - Callback when a skill is selected
- `className?: string` - Additional CSS class
- `style?: React.CSSProperties` - Additional inline styles

### Skill Interface

```typescript
interface Skill {
  id: string;
  scale: number; // 1-10 scale
  color: string;
  icon?: string;
}
```

### Hooks

- `useSkillsContext()` - Access the skills context
- `useResponsiveCanvas()` - Get responsive canvas configuration
- `useResponsiveGlobe()` - Get responsive globe configuration
- `useGlobeFocus()` - Manage globe focus state

### Constants

- `CANVAS_CONFIG` - Canvas and camera configuration
- `GLOBE_CONFIG` - Globe geometry and animation configuration
- `SKILL_POINT_CONFIG` - Skill point size and animation configuration

## Styling

The package uses CSS modules and CSS variables for styling. You can customize the appearance by overriding CSS variables:

```css
:root {
  --spacing-xs: 0.25rem;
  --spacing-sm: 0.5rem;
  --spacing-md: 1rem;
  --color-primary-md: #007bff;
  --color-light-lg: #ffffff;
  --color-dark-md: #333333;
  --color-fade-sm: rgba(0, 0, 0, 0.1);
  --font-size-sm: 0.875rem;
  --font-size-md: 1rem;
  --border-radius-sm: 0.25rem;
  --transition-md: 0.3s ease;
  --focus-outline-width: 2px;
  --focus-outline-style: solid;
  --focus-outline-color: #007bff;
  --focus-outline-offset: 2px;
}
```

## License

MIT