# 📺 Fullscreen Service for Angular

An Angular service and **directives** that provide **fullscreen control**, **reactive state**, and **template-friendly utilities**.

Originally published as a **service-only package**, this library has been **extended in a fully backward-compatible way** to include Angular directives and reactive APIs — existing applications continue to work unchanged.

---

## ✨ Features

### Core
- ✅ Optional double-tap toggle to reduce accidental activation
- ✅ Single-tap toggle by default
- 🆕 **watchFullscreen events**
- ✅ Backward-compatible service API
- ✅ Cross-browser Fullscreen API support
- ✅ No external dependencies
- ✅ Small footprint

### Enhanced (FullscreenModule)
- 🆕 **Reactive fullscreen state** (`fullscreen$`)
- 🆕 **Structural and attribute directives**
        fsToggle, fsExit, fsDoubleTap, fsActiveClass, *ifFullscreen, 
- 🆕 **Double-tap fullscreen toggle** (customizable)
- 🆕 **CSS class binding when fullscreen is active**


---

## 📦 Installation

```bash
npm install @cradokski/fullscreen
```

---

## 🚀 Basic Usage (Unchanged)

### Service Injection

```ts
import { FullScreenService } from '@cradokski/fullscreen';

@Component({...})
export class AppComponent {
  constructor(public fsService: FullScreenService) {}
}
```

### Template Example

```html
<button (click)="fsService.browserFsToggle({ requireDoubleTap: true })">
  Double Tap Toggle
</button>

<div>
  {{ fsService.isFullscreenActive() ? 'Fullscreen' : 'Normal' }}
</div>
```

✔️ **No changes required** for existing consumers.

---
## 📦 Angular Module Usage

```ts
import { FullscreenModule } from '@cradokski/fullscreen';

@NgModule({
  imports: [FullscreenModule]
})
export class AppModule {}
```

---

## 🧠 Service API

### **browserFsToggle(options?)**

```ts
browserFsToggle(options?: {
  requireDoubleTap?: boolean;
  delayMs?: number;
}): boolean
```

| Option             | Type      | Default | Description |
|--------------------|-----------|---------|-------------|
| `requireDoubleTap` | boolean   | false   | Require two taps within `delayMs` to toggle |
| `delayMs`          | number    | 300     | Maximum time between taps (ms) |

**Returns:** `true` if fullscreen is active after the call.

---

### **browserFsToggleAsync(options?)**

```ts
browserFsToggleAsync(options?): Promise<boolean>
```

Async version of `browserFsToggle`.

---

### **watchFullscreen(callback)**

```ts
watchFullscreen(
  callback: (isFullscreen: boolean, element: Element | null) => void
): () => void

```
Registers a fullscreen watcher. The Callback fires immediately with the current state and
Fires again on every fullscreen change

Returns an unwatch() cleanup function

example :
```ts
private unwatch: (() => void) | null = null;
ngOnInit(): void {
  this.unwatch = fsService.watchFullscreen((isFs, element) => {
    console.log('Fullscreen active:', isFs);
    console.log('Fullscreen element:', element?.tagName);
  });
  }
// Cleanup when no longer needed
ngOnDestroy(): void {
  if (this.unwatch) this.unwatch();
}
```
---

### **toggleFullscreen(element?)**

```ts
toggleFullscreen(element?: HTMLElement): Promise<'entered' | 'exited'>
```

Toggles fullscreen on a specific element (defaults to `<html>`).
```html
<button (click)="fsService.toggleFullscreen()">
  toggleFullscreen()
</button>
```
---

### **ensureFullscreen(element?)**

```ts
ensureFullscreen(element?): Promise<'entered'>
```

Idempotent — only enters fullscreen if not already active.
```html
<button (click)="fsService.ensureFullscreen()">
  ensureFullscreen()
</button>
```
---

### **ensureExitedFullscreen()**

```ts
ensureExitedFullscreen(): Promise<'exited'>
```

Idempotent — only exits fullscreen if active.
```html
  <button (click)="fsService.ensureExitedFullscreen()">ensureExitedFullscreen()</button>
  ```

---

### **isFullscreenActive()**

```ts
isFullscreenActive(): boolean
```

Synchronous fullscreen state check.
```html
<div *ngIf="fsService.isFullscreenActive(); else notFullscreen">
  Fullscreen Active using fsService.isFullscreenActive()
</div>
<ng-template #notFullscreen>
  Normal using fsService.isFullscreenActive()
</ng-template>
```

---

## 🔁 Reactive API

### **fullscreen$**
Observable of reactive fullscreen state 
```ts
this.fsService.fullscreen$.subscribe(state => {
  console.log("Fullscreen state changed:", state.active, state.element);
});

```

---

## 🧩 Directives

### 🔘 `fsToggle`
Toggles fullscreen mode on the host element.
```html
<button fsToggle>Toggle Fullscreen</button>
```

### 🚪 `fsExit`
Exits fullscreen mode when clicked.
```html
<button fsExit>Exit Fullscreen Mode</button>
```

### 👆 `fsDoubleTap`
Requires double-click / double-tap to toggle fullscreen.
```html
<button fsDoubleTap>Double Tap Toggle Fullscreen Mode</button>
```

### 🎨 `fsActiveClass`
Automatically adds the CSS class fs-active to the host element while fullscreen is active.
```html
<div fsActiveClass>
  I get class `.fs-active` when fullscreen mode is active
</div>

/* CSS example */
.fs-active {
  background: #0078ff;
  color: white;
}
```

### 🧱 `*ifFullscreen - Structural Directive`
Conditionally renders content only while fullscreen is active.
```html
<div *ifFullscreen>
  Visible only in fullscreen mode
</div>
```

---



## 🧪 Angular Compatibility

- Built with Angular CLI **v18.2.x**
- Compatible with **Angular v16+**
- Supports standalone components and NgModules

---

## 📄 License

MIT
