Skip to content

Usage ​

This section is for using Catnip custom elements in your app: attributes and properties, slots, DOM events, test hooks, and framework-specific patterns.

Catnip components are Web Components registered on window — they work in Vue, React, Angular, or plain HTML. For install and import, see Components overview. For runtime options (forms, i18n, types), see Configuration.

Quick mental model ​

Props map to HTML attributes. Boolean props often use presence (disabled, open). Numeric props commonly use string attributes (size="48"); with automatic type conversion enabled (default), many coerced types work as expected.

html
<catnip-icon name="user" size="24"></catnip-icon> <catnip-spinner size="32"></catnip-spinner>

Vue 3 ​

Import once (for example in main.ts). Configure the Vue compiler so catnip-* tags are custom elements — copy-paste for Vite and Nuxt is on Installation — Vue compiler. Use @click (and other @…) for DOM events; components that support two-way state emit update:modelValue.

Dynamic props (anything from script): always use leading-dot camelCase on the catnip-* host, e.g. .modelValue="selectedTags", .size="iconPx". Do not use :kebab-case or :camelCase without the dot (:modelValue, :size). Static literals may stay as plain attributes (size="24"). See Component API — Vue 3.

Nullish values on custom elements ​

Vue 3 applies patchDOMProp when you use :propName="value" on a native custom element in the template. For host properties whose runtime type is already boolean (for example after the element was set to false once), null and undefined may be coerced to false before they reach the element. That breaks patterns where null means “unset / use defaults” — the most visible Catnip example is catnip-tooltip open.

Mitigation: assign on the host from script with a template ref (for example watch(() => state, v => { el.open = v })) so null is written as a real property assignment, not through patchDOMProp’s boolean coercion path. Tooltip-specific guidance: Tooltip specs — Controlling open from Vue.

vue
<template>
  <catnip-icon name="check" size="24" />
</template>

<script setup>
import "@signicat/catnip-components";
</script>

For non-string props and modelValue, use the leading-dot shorthand (e.g. .modelValue="on", .items="tabRows") plus @update:modelValue as documented — see Component API — Props.

For form-like components that emit update:modelValue with Catnip’s event shape, register the v-catnip-model directive:

js
import { vueModelDirective } from "@signicat/catnip-components";
app.use(vueModelDirective);
vue
<template>
  <catnip-my-component v-catnip-model:myValue="formValue" />
</template>

React ​

Recommended: use @signicat/catnip-components-react — generated wrappers, property-safe props, idiomatic className / style, TypeScript types, mapped event props, SSR-safe registration, and a wrapper-only micro-frontend entry. Setup, events, slots, refs, SSR, and micro-frontends are covered on React.

Without that package, use lowercase catnip-* in JSX. Standard DOM events map to props like onClick. ref gives you the host element. Avoid passing objects or arrays as attributes unless the component documents JSON strings (for example test-selectors); set properties via ref + useEffect when needed. For custom event names (especially with :), prefer addEventListener on a ref — see Component API — Events.

jsx
<catnip-icon name="user" size="24" />
<catnip-spinner size="32" />

Angular ​

Add CUSTOM_ELEMENTS_SCHEMA to the module or standalone component that uses Catnip tags. Use Angular template bindings; for attributes vs properties, follow the same rules as for native elements and Component API — Props where Catnip expects property values.

Vanilla HTML and JavaScript ​

npm (local or bundled) ​

html
<script type="module" src="node_modules/@signicat/catnip-components/dist/catnip-components.es.js"></script>
<catnip-icon name="check" size="24"></catnip-icon>
<script>
  document.querySelector("catnip-icon").addEventListener("click", () => {});
</script>

CDN (without a bundler) ​

html
<script src="https://static.signicat.com/catnip/components/latest/catnip-components.standalone.js" defer></script>
<catnip-icon name="check" size="24"></catnip-icon>

See Installation — CDN and Configuration — CDN.

Use element.setAttribute / properties and addEventListener as with any DOM node.

TypeScript ​

Importing @signicat/catnip-components types window.Catnip. Add /// <reference types="@signicat/catnip-components" /> in the app’s env.d.ts. Vue still needs isCustomElement for catnip-* — see Installation — Vue compiler and Installation — TypeScript.

For tag completion in HTML and Vue templates, point the editor at html-custom-data.json: Installation — Editor autocomplete. Prop names in docs use camelCase; plain HTML uses kebab-case attributes; Vue templates should use camelCase bindings (see Component API — Vue 3).

Where to go next ​

TopicGuide
Coding agentsAgent skill
React (@signicat/catnip-components-react)React
Attributes, modelValue, leading-dot bindsComponent API — Props
Default and named slotsComponent API — Slots
CustomEvent, detail, listenersComponent API — Events
data-test / testSelectorsComponent API — Test selectors
CatnipConfig, forms, i18nConfiguration
Live experimentationPlayground
Per-component APISidebar Catalogue — e.g. Button, Tooltip

Catnip Design System by Signicat