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). Vue treats catnip-* as custom elements. 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, TypeScript types, and mapped event props. Setup, slots, refs, and links to the component catalogue are 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

Global Vue types for catnip-* tags are provided when you follow the package’s typing setup (see the components package and your app’s tsconfig). 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
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