npm package: @gringow/gringow-shadow
Description: A HTML class for Gringow AI-powered translation tool
Author: Renato Gaspar
Latest version: 0.3.0

# @gringow/gringow-shadow

[![npm version](https://img.shields.io/npm/v/@gringow/gringow-shadow)](https://www.npmjs.com/package/@gringow/gringow-shadow)
[![License: MIT](https://img.shields.io/badge/License-MIT-blue.svg)](https://opensource.org/licenses/MIT)

Lightweight Web Component layer for Gringow translations. Provides the `<g-gringow>` custom element, translation store, and language change events for vanilla JavaScript projects. This is the foundation layer used by [@gringow/gringow-react](https://www.npmjs.com/package/@gringow/gringow-react).

## Features

- 🎯 **Custom Element** - `<g-gringow>` for declarative translations
- 🗂️ **Translation Store** - Singleton cache manager with language awareness
- 📡 **Language Events** - Type-safe language change broadcasting
- 🪶 **Lightweight Runtime** - Pure Web Components API usage
- ⚡ **Framework Agnostic** - Works with vanilla JS, React, Vue, etc.
- 🔄 **Smart Caching** - Memoized cache fetching and lookup

## Installation

```bash
# Using pnpm
pnpm add @gringow/gringow-shadow

# Using npm
npm install @gringow/gringow-shadow

# Using yarn
yarn add @gringow/gringow-shadow
```

## Quick Start

### Vanilla HTML Setup

```html
<!DOCTYPE html>
<html lang="en">
<head>
  <meta name="gringow-cache-url" content="/gringow/gringow.json">
</head>
<body>
  <g-gringow data-cache-id="grw_abc123" data-flatten="Hello world"></g-gringow>
  
  <button id="btn-pt">Português</button>
  <button id="btn-fr">Français</button>

  <script type="module">
    import { GringowComponent, GringowStore, LanguageChangeEvent } from '@gringow/gringow-shadow'

    // Configure store
    GringowStore.cacheUrl = '/gringow/gringow.json'
    GringowStore.language = 'en-US'
    await GringowStore.fetchCache()

    // Register custom element
    GringowComponent.defaults = { store: GringowStore }
    customElements.define(GringowComponent.GRINGOW_ELEMENT_NAME, GringowComponent)

    // Handle language changes
    document.getElementById('btn-pt').onclick = () => {
      dispatchEvent(LanguageChangeEvent.create('pt-BR'))
    }
    
    document.getElementById('btn-fr').onclick = () => {
      dispatchEvent(LanguageChangeEvent.create('fr-CA'))
    }

    // Listen to language changes
    addEventListener(LanguageChangeEvent.EVENT_NAME, (event) => {
      console.log('Language changed to:', event.detail.lang)
    })
  </script>
</body>
</html>
```

## Component API

### `<g-gringow>` Custom Element

Declarative translation component that reads from the cache and updates on language changes.

#### Attributes

- **`data-cache-id`** (required) - Cache ID from `gringow.json` (e.g., `grw_abc123`)
- **`data-flatten`** (required) - Original flattened string used as fallback

### GringowStore (Singleton)

Central cache manager for fetching and accessing translations.

#### Properties

```typescript
// Cache file URL (auto-detects from <meta> or <html data-gringow-cache-url>)
GringowStore.cacheUrl: string | null

// Active language (defaults to document.documentElement.lang)
GringowStore.language: string | null

// Cached translations object
GringowStore.cache: GringowCache | null
```

#### Methods

```typescript
// Fetch and memoize cache from cacheUrl
await GringowStore.fetchCache(): Promise<void>

// Get translated string for active language
await GringowStore.getCacheItem(cacheId: string): Promise<string | null>

// Manual cache setter
GringowStore.setCache(cache: GringowCache): void
```

#### Configuration Priority

The store resolves `cacheUrl` in this order:

1. `GringowStore.cacheUrl` (programmatic)
2. `<html data-gringow-cache-url="/path/to/cache.json">`
3. `<meta name="gringow-cache-url" content="/path/to/cache.json">`

### LanguageChangeEvent

Custom event for broadcasting language changes across components.

#### Usage

```typescript
// Dispatch language change
dispatchEvent(LanguageChangeEvent.create('pt-BR'))

// Listen for changes
addEventListener(LanguageChangeEvent.EVENT_NAME, (event) => {
  console.log('New language:', event.detail.lang)
  // event.detail.lang === 'pt-BR'
})
```

#### Constants

- **`LanguageChangeEvent.EVENT_NAME`** - `'language-change'`
- **`LanguageChangeEvent.create(lang: string)`** - Factory method for events

## Advanced Examples

### Dynamic Content

```html
<script type="module">
  import { GringowComponent, GringowStore } from '@gringow/gringow-shadow'

  GringowStore.cacheUrl = '/gringow/gringow.json'
  GringowStore.language = 'en-US'
  await GringowStore.fetchCache()

  GringowComponent.defaults = { store: GringowStore }
  customElements.define('g-gringow', GringowComponent)

  // Dynamically create element
  const element = document.createElement('g-gringow')
  element.setAttribute('data-cache-id', 'grw_welcome')
  element.setAttribute('data-flatten', 'Welcome back, Alice!')
  document.body.appendChild(element)
</script>
```

### Multiple Language Switcher

```html
<nav>
  <button data-lang="en-US">English</button>
  <button data-lang="pt-BR">Português</button>
  <button data-lang="fr-CA">Français</button>
  <button data-lang="es-ES">Español</button>
</nav>

<main>
  <g-gringow data-cache-id="grw_title" data-flatten="Welcome"></g-gringow>
  <g-gringow data-cache-id="grw_desc" data-flatten="Choose your language"></g-gringow>
</main>

<script type="module">
  import { GringowComponent, GringowStore, LanguageChangeEvent } from '@gringow/gringow-shadow'

  // Setup
  GringowStore.cacheUrl = '/gringow/gringow.json'
  GringowStore.language = document.documentElement.lang || 'en-US'
  await GringowStore.fetchCache()

  GringowComponent.defaults = { store: GringowStore }
  customElements.define('g-gringow', GringowComponent)

  // Wire language buttons
  document.querySelectorAll('[data-lang]').forEach(btn => {
    btn.onclick = () => {
      const lang = btn.dataset.lang
      document.documentElement.lang = lang
      dispatchEvent(LanguageChangeEvent.create(lang))
    }
  })
</script>
```

### Framework Integration (Vue/Svelte/etc)

```typescript
// utils/gringow.ts
import { GringowComponent, GringowStore, LanguageChangeEvent } from '@gringow/gringow-shadow'

export async function initGringow(cacheUrl: string, initialLang: string) {
  GringowStore.cacheUrl = cacheUrl
  GringowStore.language = initialLang
  await GringowStore.fetchCache()

  GringowComponent.defaults = { store: GringowStore }
  
  if (!customElements.get('g-gringow')) {
    customElements.define('g-gringow', GringowComponent)
  }
}

export function changeLanguage(lang: string) {
  dispatchEvent(LanguageChangeEvent.create(lang))
}
```

## Module Exports

The package provides granular exports for tree-shaking:

```typescript
// Main export (all components)
import { GringowComponent, GringowStore, LanguageChangeEvent } from '@gringow/gringow-shadow'

// Individual exports
import { GringowComponent } from '@gringow/gringow-shadow/component'
import { GringowStore } from '@gringow/gringow-shadow/store'
import { LanguageChangeEvent } from '@gringow/gringow-shadow/event'
```

## Development

```bash
# Install dependencies
pnpm install

# Build the package
pnpm run build

# Watch mode for development
pnpm run watch
```

## Browser Compatibility

Built on Web Components standards:
- Custom Elements v1
- Shadow DOM v1
- ES2020+ modules

**Supported browsers**: Chrome 54+, Firefox 63+, Safari 10.1+, Edge 79+

## Related Packages

Gringow provides a complete ecosystem for AI-powered translation:

- **[@gringow/gringow](https://www.npmjs.com/package/@gringow/gringow)** - Core translation library
- **[@gringow/gringow-vite](https://www.npmjs.com/package/@gringow/gringow-vite)** - Vite plugin for build-time extraction
- **[@gringow/gringow-react](https://www.npmjs.com/package/@gringow/gringow-react)** - React hooks and components
- **[@gringow/gringow-shadow](https://www.npmjs.com/package/@gringow/gringow-shadow)** - Web Component layer
- **[@gringow/gringow-cli](https://www.npmjs.com/package/@gringow/gringow-cli)** - CLI tool
- **[@gringow/gringow-nextjs](https://www.npmjs.com/package/@gringow/gringow-nextjs)** - Next.js plugin (experimental)

## Resources

- [Documentation](https://gringow.dev)
- [GitHub Repository](https://github.com/rntgspr/gringow)
- [Example: Vanilla HTML](https://github.com/rntgspr/gringow/tree/main/example-html)

## License

MIT © [Renato Gaspar](https://github.com/rntgspr)

---

**Questions?** Open an issue on [GitHub](https://github.com/rntgspr/gringow/issues)