# Dynamic UI Hooks Reference

> Components: useDPortalContext, useFormatCurrency

---

## Import Pattern

All hooks are imported from the main package:

```typescript
import {
  useFormatCurrency,
  useDPortalContext
} from '@dynamic-framework/ui-react';
```

---

## useDPortalContext

Hook for managing modal/portal components.

---

### 📋 SNIPPET: Portal Context Pattern

```tsx
// ==============================================================================
// SNIPPET: useDPortalContext Hook Usage
// COPY THIS pattern for modal management
// ==============================================================================

import { useDPortalContext } from '@dynamic-framework/ui-react';

function MyComponent() {
  const { openPortal, closePortal } = useDPortalContext();

  // Opening a portal (MUST pass two arguments)
  const handleOpenModal = () => {
    openPortal('my-modal', {});  // ✅ Second argument required (empty object if no props)
  };

  // Closing a portal (NO arguments)
  const handleCloseModal = () => {
    closePortal();  // ✅ No arguments needed
  };

  // Opening with data
  const handleOpenWithData = (userId: number) => {
    openPortal('edit-modal', { userId });  // ✅ Pass props as second argument
  };

  return (
    <>
      <button onClick={handleOpenModal}>Open Modal</button>
      <MyModal onClose={handleCloseModal} />
    </>
  );
}

// ==============================================================================
// SNIPPET END
// ==============================================================================
```

---

### Signature

```typescript
const { openPortal, closePortal } = useDPortalContext();

// openPortal: (portalName: string, props: object) => void
// closePortal: () => void
```

### Return Value

- `openPortal: (portalName: string, props: object) => void` - Opens a registered portal
- `closePortal: () => void` - Closes the current portal (no arguments)

---

### ❌ Common Mistakes

```tsx
// ❌ WRONG: Missing second argument
openPortal('my-modal');  // Error: Expected 2 arguments, but got 1

// ❌ WRONG: Passing portal name to closePortal
closePortal('my-modal');  // Error: Expected 0 arguments, but got 1

// ✅ CORRECT
openPortal('my-modal', {});  // Empty object if no props needed
closePortal();               // No arguments
```

---

### DContextProvider Setup

Portals must be registered in DContextProvider at app root:

```tsx
import { DContextProvider } from '@dynamic-framework/ui-react';
import MyModal from './components/MyModal';

<DContextProvider
  availablePortals={{
    'my-modal': MyModal,           // key is portal name
    'confirm-dialog': ConfirmDialog,
  }}
>
  <App />
</DContextProvider>
```

---

## useFormatCurrency

Hook for formatting currency values with locale and symbol support.

---

### 📋 SNIPPET: useFormatCurrency Hook Pattern

```tsx
// ==============================================================================
// SNIPPET: useFormatCurrency Hook Usage
// COPY THIS pattern for currency formatting
// ==============================================================================

import { useFormatCurrency } from '@dynamic-framework/ui-react';

function PriceDisplay({ amount }: { amount: number }) {
  // ✅ CORRECT: Destructure format method
  const { format } = useFormatCurrency();

  return <div>{format(amount)}</div>;  // Output: "$1,234.56"
}

// With custom options
function CustomCurrencyDisplay({ amount, currency }: Props) {
  const { format } = useFormatCurrency();

  return (
    <div>
      {format(amount, { symbol: currency, precision: 2 })}
    </div>
  );
}

// ==============================================================================
// SNIPPET END
// ==============================================================================
```

---

### Signature

```typescript
const { format, values } = useFormatCurrency();
```

### Return Value

Returns an object with:
- `format: (value: number, options?: CurrencyProps) => string` - Function to format a number as currency
- `values: string[]` - Array of available currency codes

---

### ❌ Common Mistakes

```tsx
// ❌ WRONG: Trying to use hook return as function
const format = useFormatCurrency();
format(100);  // Error: format is not a function

// ✅ CORRECT: Destructure the format method
const { format } = useFormatCurrency();
format(100);  // Works: "$100.00"
```

---

## Best Practices

### useDPortalContext
- ✅ Always pass second argument to `openPortal` (use `{}` if no props)
- ✅ Never pass arguments to `closePortal`
- ✅ Register all portals in `DContextProvider.availablePortals`
- ✅ Use descriptive portal names (kebab-case recommended)

### useFormatCurrency
- ✅ Always destructure `{ format }` from the hook
- ✅ Use for all currency display (consistent formatting)
- ✅ Store raw numbers in state/Zustand, format only for display
- ✅ Can pass custom options for different currencies

---

**Related Documentation:**
- See `modals.md` for DModal and DOffcanvas usage with useDPortalContext
- See `inputs.md` for DInputCurrency (uses currency formatting internally)
