# Infoland Component Library

Vue 3 component library with Riot.js wrappers (Vue-mounted).

> **📦 This library replaces `infoland-flex-search`**
> 
> If you're migrating from `infoland-flex-search`, see the [Migration Guide](./MIGRATION_FROM_FLEX_SEARCH.md).

## 🎯 Quick Start

### Vue 3
```bash
npm install @ambita/infoland-component-library
```

```typescript
// main.ts
import { initLibraryConfig } from '@ambita/infoland-component-library/vue'
import '@ambita/infoland-component-library/vue/style.css'

initLibraryConfig({
  environment: import.meta.env.VITE_INFOLAND_ENV
})
```

```vue
<script setup lang="ts">
import { SearchComponent } from '@ambita/infoland-component-library/vue'
</script>

<template>
  <SearchComponent />
</template>
```

### Riot.js (recommended lifecycle helper)
```javascript
import { initLibraryConfig, useOfsInRiot } from '@ambita/infoland-component-library/riot'
import '@ambita/infoland-component-library/riot/style.css'

initLibraryConfig({
  environment: 'beta'
})

this.on('before-mount', () => {
  this.ofs = useOfsInRiot(this, {
    ref: 'container',
    getProps: () => ({ autofocus: true }),
    onSearchResult: (result) => console.log('OFS result', result),
  })
})
```

For lower-level/manual lifecycle control, `createOfsWrapper` and `createVueWrapper`
are still available.

## 📚 Documentation

- **[Full Documentation](./docs/index.md)** - Complete guide
- **[Quick Reference](./docs/quick-reference.md)** - Cheat sheet
- **[Vue Usage Guide](./docs/guides/vue-usage.md)** - Using in Vue 3
- **[Development Guide](./docs/guides/development.md)** - Contributing
- **[npm link Workflow](./docs/guides/npm-link-workflow.md)** - Local development

## 🛠️ Development

### Available Scripts

```bash
npm run dev              # Storybook at http://localhost:6006
npm run build            # Production build (Vue + Riot)
npm run build:vue        # Build Vue only
npm run build:riot       # Build Riot bundle only
npm run build:watch      # Watch mode (Vue + Riot)
npm test                 # Run tests
npm run type-check       # TypeScript check
```

## 🎨 Features

- ✅ **Vue 3 components** with full TypeScript support
- ✅ **Riot.js wrappers** for Vue components
- ✅ **Design System Styling** via DS tokens and components
- ✅ **Shared Services** for API access
- ✅ **Tested** with Vitest

## 📦 What's Included

### Components
- `SearchComponent` - Multi-step search interface
- `SearchInput` - Search input field
- `MapComponent` - Map display component

### Services
- `userService`
- `apiService`

### Utilities
- Riot.js event helpers (`on`, `onMany`, `withData`, `debounce`, `throttle`)
- Vue composables (`useApi`, `useConfig`)
- TypeScript types

## 🧱 Project Structure

```
src/
├── components/          # Vue 3 components
├── composables/         # Vue composables
├── styles/              # Design system styles and tokens
│   └── components/
├── services/            # API and domain services
├── models/              # Shared models and types
├── config/              # Library configuration
├── utils/               # Shared utilities
└── riot/                # Riot.js wrappers/helpers
```

## 🔧 Configuration

Vue and Riot wrappers share the same configuration API:

```typescript
import { initLibraryConfig } from '@ambita/infoland-component-library/vue'
// or
import { initLibraryConfig } from '@ambita/infoland-component-library/riot'

initLibraryConfig({
  environment: 'beta',
  apiTimeout: 30000,
  enableLogging: true
})
```

## 📦 Package Exports

```json
{
  "@ambita/infoland-component-library": "Vue components (default)",
  "@ambita/infoland-component-library/vue": "Vue 3 components",
  "@ambita/infoland-component-library/riot": "Riot.js wrappers",
  "@ambita/infoland-component-library/vue/style.css": "Vue styles",
  "@ambita/infoland-component-library/riot/style.css": "Riot styles"
}
```

## 🚀 Release workflow

Releases are fully automated via [semantic-release](https://github.com/semantic-release/semantic-release).

### How it works

1. Merge a PR into `main`.
2. The **Release & Publish** GitHub Actions workflow runs automatically.
3. semantic-release reads all commits since the last tag and decides the next version:

| Commit prefix | Version bump |
|---|---|
| `fix: ...` | patch (1.0.0 → 1.0.1) |
| `feat: ...` | minor (1.0.0 → 1.1.0) |
| `BREAKING CHANGE:` in footer | major (1.0.0 → 2.0.0) |
| `chore:`, `docs:`, `refactor:`, `test:` | no release |

4. If there is something to release: `package.json` is bumped, `docs/changelog.md`
   is updated, the package is published to npm, and a GitHub Release is created.
5. A Slack message is sent to `#infoland-deployment` with the version and a list
   of what changed.

### Sending to the #releases channel

Go to **GitHub Actions → Release & Publish → Run workflow**, tick
**"Send notification to the #releases channel"**, and run. This is intended for
significant releases you want to announce broadly. Everyday releases only notify
`#infoland-deployment`.

## 📝 License

MIT
