DOCS
v0.4

Vanilla HTML / Any Framework

Import once, use everywhere. No framework adapter needed.

<script type="module">
  import '@cognivo/components';
</script>
<link rel="stylesheet" href="node_modules/@cognivo/tokens/dist/index.css">

<cg-button variant="primary" size="md">Click me</cg-button>
<ai-chat placeholder="Ask anything..."></ai-chat>
<ai-thinking variant="dots" text="Analyzing..."></ai-thinking>

      
Web Components work natively in Angular, Svelte, Astro, SolidJS, and any framework that renders to the DOM. No wrappers required.

React

Type-safe React wrappers with proper event handling and prop mapping.

Installation

pnpm add @cognivo/adapter-react @cognivo/components @cognivo/tokens

Setup

// app.tsx or layout.tsx — import tokens CSS once
import '@cognivo/tokens/dist/index.css';

Usage

import { CgButton, CgInput, CgCard, AiChat, AiThinking } from '@cognivo/adapter-react';

function Dashboard() {
  const [query, setQuery] = useState('');

  return (
    <div>
      <CgCard variant="elevated">
        <CgInput
          label="Search"
          value={query}
          onCgInput={(e) => setQuery(e.detail.value)}
        />
        <CgButton variant="primary" onCgClick={() => search(query)}>
          Search
        </CgButton>
      </CgCard>

      <AiThinking variant="dots" text="Processing..." />
      <AiChat placeholder="Ask a question..." />
    </div>
  );
}

Event Handling

React wrappers map Web Component custom events to React-style callbacks. The event prefix is on + PascalCase event name.

Web Component EventReact PropDetail Type
cg-clickonCgClickMouseEvent
cg-inputonCgInput{ value: string }
cg-changeonCgChange{ value: string, error?: boolean }
ai-messageonAiMessage{ text: string, role: string }

TypeScript

// All props and events are fully typed
import type { CgButton, CgInput, AiChat } from '@cognivo/adapter-react';

// Example: typed event handler
const handleInput = (e: CustomEvent<{ value: string }>) => {
  console.log(e.detail.value);
};

Vue

Vue 3 wrappers with v-model support and typed props.

Installation

pnpm add @cognivo/adapter-vue @cognivo/components @cognivo/tokens

Setup

// main.ts
import '@cognivo/tokens/dist/index.css';

Usage

<script setup lang="ts">
import { CgButton, CgInput, CgCard, AiChat } from '@cognivo/adapter-vue';
import { ref } from 'vue';

const query = ref('');
</script>

<template>
  <CgCard variant="elevated">
    <CgInput
      label="Search"
      :value="query"
      @cg-input="query = $event.detail.value"
    />
    <CgButton variant="primary" @cg-click="search(query)">
      Search
    </CgButton>
  </CgCard>

  <AiChat placeholder="Ask a question..." />
</template>

      

Event Handling

Vue wrappers emit the same custom events as the Web Components. Use @event-name syntax.

Svelte, Angular, SolidJS

No adapter needed — use Web Components directly.

Svelte

<script>
  import '@cognivo/components';
  import '@cognivo/tokens/dist/index.css';
</script>

<cg-button variant="primary" on:cg-click={handleClick}>
  Click me
</cg-button>

      

Angular

// app.module.ts — enable custom elements
import { CUSTOM_ELEMENTS_SCHEMA } from '@angular/core';

@NgModule({
  schemas: [CUSTOM_ELEMENTS_SCHEMA],
})
export class AppModule {}

// Import in styles.css
@import '@cognivo/tokens';

// Use in templates
// <cg-button variant="primary">Click</cg-button>

Dark Mode (All Frameworks)

// Set on document root — works in all frameworks
document.documentElement.setAttribute('data-theme', 'dark');

// React example
function ThemeToggle() {
  const [dark, setDark] = useState(true);
  useEffect(() => {
    document.documentElement.setAttribute(
      'data-theme', dark ? 'dark' : 'light'
    );
  }, [dark]);
  return <CgSwitch checked={dark} onCgChange={() => setDark(!dark)} />;
}

Tree Shaking

Import individual components to reduce bundle size:

// Full library (registers all 182 components)
import '@cognivo/components';

// Individual imports (tree-shakeable)
import { CgButton } from '@cognivo/components';
import { AiChat } from '@cognivo/components';

Server-Side Rendering

Cognivo components SSR cleanly via @lit-labs/ssr. The @cognivo/ssr package provides ergonomic helpers that render Lit templates to a string with Declarative Shadow DOM, so the markup is visible on first paint before hydration.

Installation

pnpm add @cognivo/ssr @cognivo/components lit

Core Usage

import { renderToString, html } from '@cognivo/ssr';
import '@cognivo/components';

const markup = renderToString(html`
  <cg-card>
    <cg-button variant="primary">Click me</cg-button>
  </cg-card>
`);

Next.js (App Router)

Render on the server, then import the client bundle to upgrade the custom elements after hydration.

// app/page.tsx — Server Component
import { renderToString, html } from '@cognivo/ssr';
import '@cognivo/components'; // registers element classes for SSR

export default function Page() {
  const markup = renderToString(html`
    <cg-card>
      <cg-button variant="primary">Get started</cg-button>
    </cg-card>
  `);

  return <div dangerouslySetInnerHTML={{ __html: markup }} />;
}
// app/cognivo-client.tsx — Client Component
'use client';
import { useEffect } from 'react';

export function CognivoClient() {
  useEffect(() => {
    // Upgrades the custom elements in the SSR'd markup
    import('@cognivo/components');
  }, []);
  return null;
}

Astro

Use set:html with the rendered markup, then ship a client script that registers the elements for hydration.

---
import { renderToString, html } from '@cognivo/ssr';
import '@cognivo/components';

const markup = renderToString(html`
  <cg-card>
    <cg-button variant="primary">Click me</cg-button>
  </cg-card>
`);
---

<div set:html={markup}></div>

<script>
  import '@cognivo/components';
</script>

      

Remix

The same pattern works in Remix: call renderToString inside your loader or route module, emit the HTML in the response, and import @cognivo/components in the client entry to upgrade the elements after hydration.

Caveat: Declarative Shadow DOM is supported natively in Chromium 111+, Safari 16.4+, and Firefox 123+. For older browsers, ship the @webcomponents/template-shadowroot polyfill alongside the client bundle.