GridKit Web Components provides design-system elements that work in any web application. They are native custom elements built with Lit, so they can be used in plain HTML, Angular, Vue, React, or another framework.
Available elements: gd-avatar, gd-badge, gd-box, gd-button, gd-checkbox, gd-icon, gd-image, gd-input, gd-input-file, gd-label, gd-link, gd-loader, gd-select, gd-separator, gd-skeleton, gd-slider, gd-slider-dots, gd-switch, gd-textarea, gd-toggle, gd-truncate, gd-typography, gd-wrapper, gd-counter, and gd-menu.
npm install web-components gd-design-libraryImport the library once to register its custom elements. Each element needs a GridKit theme; assign it as a JavaScript property, not as an HTML attribute.
import 'web-components';
import { defaultTheme } from 'gd-design-library/tokens';
document.querySelectorAll<HTMLElement & { theme: unknown }>('gd-button, gd-checkbox, gd-input').forEach((element) => {
element.theme = defaultTheme;
});<gd-button variant="primary">Save</gd-button>
<gd-checkbox>Accept terms</gd-checkbox>
<gd-input label="Email" placeholder="name@example.com"></gd-input>
<gd-typography variant="h1" as="h1">Welcome</gd-typography>Use attributes for strings and booleans, such as variant, label, and disabled. Pass objects, arrays, and controlled values as JavaScript properties. Components emit native custom events: gd-input returns { value }, while gd-change returns the selected value or checkbox state.
Register the elements once (for example, in main.ts), then allow custom elements in the consuming component or module.
// main.ts
import 'web-components';
// app.component.ts
import { Component, CUSTOM_ELEMENTS_SCHEMA } from '@angular/core';
import { defaultTheme } from 'gd-design-library/tokens';
@Component({
selector: 'app-root',
schemas: [CUSTOM_ELEMENTS_SCHEMA],
template: `
<gd-input [theme]="theme" label="Email" [value]="email" (gd-input)="email = $event.detail.value"></gd-input>
<gd-checkbox [theme]="theme" [checked]="accepted" (gd-change)="accepted = $event.detail.checked">
Accept terms
</gd-checkbox>
<gd-button [theme]="theme" variant="primary" (click)="save()">Save</gd-button>
`,
})
export class AppComponent {
theme = defaultTheme;
email = '';
accepted = false;
save() {}
}Use Angular property bindings ([theme], [items], [value]) for non-string values and event bindings ((gd-input), (gd-change)) for component events.
Register the elements once in your app entry file. In templates, use .prop for object values and component state.
// main.ts
import { createApp } from 'vue';
import 'web-components';
import App from './App.vue';
createApp(App).mount('#app');<script setup lang="ts">
import { ref } from 'vue';
import { defaultTheme } from 'gd-design-library/tokens';
const email = ref('');
const accepted = ref(false);
</script>
<template>
<gd-input :theme.prop="defaultTheme" label="Email" :value.prop="email" @gd-input="email = $event.detail.value" />
<gd-checkbox :theme.prop="defaultTheme" :checked.prop="accepted" @gd-change="accepted = $event.detail.checked">
Accept terms
</gd-checkbox>
<gd-button :theme.prop="defaultTheme" variant="primary">Save</gd-button>
</template>The shared Storybook is started from the repository root with npm run storybook and
opened at http://localhost:6006. Its Web Components section contains native stories, Controls, and docs for all twenty-five
existing elements. Interactive stories show native event payloads below the component.
| Storybook component | React-contract coverage |
|---|---|
| Avatar | Image, fallback, badge, every size, custom colors |
| Badge | Variants, appearances, sizes, disabled state, and icon slots |
| Box | Vertical/horizontal layout, borders, highlight, shadow hover, and slotted content |
| Button | Every variant and radius, full-width, icon-only, loading, disabled, icon slots |
| Checkbox | Checked, indeterminate, disabled, both sizes; gd-change → { checked } |
| Input | Types, validation colors, read-only/disabled, adornments; gd-input/gd-change |
| Image | Loading placeholder, fallback slot, caption, sizing, object fit, and load/error events |
| Icon | All built-in icons from the shared core catalog, token sizes, and theme-aware fills |
| InputFile | Accept/capture/multiple/disabled behavior, custom label, icon label, and gd-change file detail |
| Label | Native label association, slotted content, icons, and style overrides |
| Link component | Variants, sizes, underline states, disabled semantics, targets, and href |
| Loader | Circle/dots, sizes, rounded dots, wrappers, section, and native full-page top layer |
| Select | Single/multiple, search, auto-open, colors, adornments, custom initiator; gd-change |
| Separator | Orientations, line variants, thickness, labels, semantic elements, lengths, and colors |
| Skeleton | Rounded/rectangular/circular shapes, dimensions, colors, animation control, and child content |
| Slider | Range limits, controlled values, keyboard input, disabled state, visual fill, and events |
| SliderDots | Accessible carousel tabs, active state, larger sets, and selection events |
| Switch | Checked, disabled, loading, controlled/uncontrolled behavior, label placement, and events |
| Textarea | Values, colors, resize modes, dynamic height, focus, character limits, and input/change events |
| Toggle | String/object items, selected value, disabled state, custom item rendering, and change events |
| Truncate | Single/multiple-line truncation, style overrides, overflow measurement, and accessibility |
| Typography | All 18 variants, display sizes, style variants, alignment/color controls, semantic override |
| Wrapper | Inline, section and full-page layout variants, semantic tag override, content, and styles |
| Counter | Minimum/maximum, custom range, disabled; gd-change → { value: number } |
| Menu | Placement, offsets, height constraints, close/persist behavior; gd-change → { data, value } |
The ports preserve each source component's component-specific public contract using native
custom-element equivalents. Primitive props remain attributes/properties; objects, arrays,
functions, themes, and style objects are JavaScript properties. React callbacks become native
DOM/custom events, ReactNode props become default or named slots, and imperative refs become
public element methods. Generic React/Emotion box props are supplied with host CSS or the
component's styles property rather than reproduced as React-only prop names.
react-parity.json records the required mapping and Storybook examples for every shipped port.
npm run check:web-components-ports fails when an element, required mapping, or parity story is
missing. Unit tests cover the programmatic property/event contract; the Storybook smoke test also
checks representative interactions, semantic output, and visual state for the interactive ports in Chromium.
There is no separate Web Components Storybook command. Run npm run build-storybook
then node bin/storybook/smoke-test.mjs to verify every native story and representative
interactions in Chromium. The Angular and Vue harnesses cover the complete supported catalog.
Start the development server for all Web Components examples:
npm install
npm run dev:web-componentsVite prints the local URL in the terminal (usually http://localhost:5173). The command does not select a framework or open a page by default. Choose the example you want in the browser:
- Angular:
http://localhost:5173/harness/fidelity-check.html - Vue:
http://localhost:5173/harness/fidelity-check-vue.html
Build the library with:
npm run build:web-components