Skip to content

Latest commit

 

History

History
167 lines (131 loc) · 11.3 KB

File metadata and controls

167 lines (131 loc) · 11.3 KB

GridKit Web Components

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.

Install

npm install web-components gd-design-library

Import 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;
});

Use in HTML

<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.

Angular

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.

Vue

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>

Run locally

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 }

React-to-custom-element contract

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-components

Vite 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