npm package: @lightspeed/crane-api
Description: Lightweight runtime API package for building custom sections and templates with `@lightspeed/crane`.
Latest version: 2.2.1

# @lightspeed/crane-api

Lightweight runtime API package for building custom sections and templates with `@lightspeed/crane`.

This package provides Vue 3 composables and TypeScript types needed for custom sections and templates, without CLI or build tools.

## Installation

```bash
npm install @lightspeed/crane-api
```

> **Note:** This package is automatically included when using `@lightspeed/crane`. Install separately only if you need the API without the CLI.

## Overview

The package exports:

- **App Creation** — `createVueServerApp`, `createVueClientApp` for SSR/hydration
- **Content Composables** — Access user-editable content (text, images, buttons, etc.)
- **Design Composables** — Access styling settings (colors, fonts, backgrounds)
- **Types** — TypeScript definitions for data structures

## App Entry Points

Every section requires two entry points for SSR and client hydration:

```typescript
// server.ts — SSR rendering
import { createVueServerApp } from '@lightspeed/crane-api';
import Section from './Section.vue';
import type { ContentType, DesignType } from './type';

export default createVueServerApp<ContentType, DesignType>(Section);
```

```typescript
// client.ts — Client hydration
import { createVueClientApp } from '@lightspeed/crane-api';
import Section from './Section.vue';
import type { ContentType, DesignType } from './type';

export default createVueClientApp<ContentType, DesignType>(Section);
```

## Content Composables

Access content defined in `settings/content.ts`:

| Composable | Editor Type | Return Type |
|------------|-------------|-------------|
| `useInputboxElementContent` | INPUTBOX | `Reactive<InputBoxContent>` |
| `useTextareaElementContent` | TEXTAREA | `Reactive<TextAreaContent>` |
| `useButtonElementContent` | BUTTON | `Reactive<ButtonContentData>` |
| `useImageElementContent` | IMAGE | `Reactive<ImageContent>` |
| `useToggleElementContent` | TOGGLE | `Reactive<ToggleContent>` |
| `useSelectboxElementContent` | SELECTBOX | `Reactive<SelectBoxContent>` |
| `useDeckElementContent` | DECK | `Reactive<DeckContent>` |
| `useCategorySelectorElementContent` | CATEGORY_SELECTOR | `Reactive<CategorySelector>` |
| `useProductSelectorElementContent` | PRODUCT_SELECTOR | `Reactive<ProductSelector>` |
| `useLogoElementContent` | LOGO | `Reactive<LogoContent>` |
| `useMenuElementContent` | MENU | `Reactive<MenuContent>` |
| `useNavigationMenuElementContent` | NAVIGATION_MENU | `Reactive<MenuContent>` |
| `useTranslation` | — | Translation helper |

### Example

```typescript
import { useInputboxElementContent, useImageElementContent } from '@lightspeed/crane-api';
import type { ContentType } from './type';

const title = useInputboxElementContent<ContentType>('title');
const image = useImageElementContent<ContentType>('hero_image');

```

## Design Composables

Access design settings defined in `settings/design.ts`:

| Composable | Editor Type | Return Type |
|------------|-------------|-------------|
| `useTextElementDesign` | TEXT | `Reactive<TextDesignData>` |
| `useTextareaElementDesign` | TEXTAREA | `Reactive<TextareaDesignData>` |
| `useButtonElementDesign` | BUTTON | `Reactive<ButtonDesignData>` |
| `useBackgroundElementDesign` | BACKGROUND | `Reactive<BackgroundDesignData>` |
| `useImageElementDesign` | IMAGE | `Reactive<ImageDesignData>` |
| `useToggleElementDesign` | TOGGLE | `Reactive<ToggleDesignData>` |
| `useSelectboxElementDesign` | SELECTBOX | `Reactive<SelectboxDesignData>` |
| `useLayoutElementDesign` | — | `Reactive<LayoutDesignData>` |
| `useLogoElementDesign` | LOGO | `ComputedRef<LogoDesignData>` |

### Example

```typescript
import { useTextElementDesign, useBackgroundElementDesign } from '@lightspeed/crane-api';
import type { DesignType } from './type';

const titleStyle = useTextElementDesign<DesignType>('title_style');
const background = useBackgroundElementDesign<DesignType>('section_background');

```

## Working with DECK

DECK allows collections of cards. Use `getReactiveRef` to access card fields:

```typescript
import { useDeckElementContent, EditorTypes } from '@lightspeed/crane-api';
import type { ContentType } from './type';

const slides = useDeckElementContent<ContentType>('slides');

slides.cards?.forEach(card => {
  const title = slides.getReactiveRef(card, EditorTypes.INPUTBOX, 'title');
  const image = slides.getReactiveRef(card, EditorTypes.IMAGE, 'background');
  const button = slides.getReactiveRef(card, EditorTypes.BUTTON, 'cta');
});
```

## Requirements

- Node.js >= 20
- Vue >= 3.4