# Glide UI Components

A modern, **SSR-ready** React component library built with TypeScript, Tailwind CSS, and Radix UI primitives. Features fully accessible, mobile-responsive components for building professional web applications. Compatible with Next.js, Remix, and other server-side rendering frameworks.

## Documentation

- 📚 **[Component Catalog](src/components/ALL_COMPONENTS.md)** - Complete list of all available components
- 🛠️ **[Development Guide](src/components/COMPONENT_DEVELOPMENT_GUIDE.md)** - Guidelines for creating new components

## Installation

```bash
npm install @glide/glide-ui
```

## CDN Usage

You can load glide-ui directly via `<script>` and `<link>` tags from the Fling CDN without npm.

### Quick Start

Copy-paste this HTML file to get started:

```html
<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>Glide UI CDN Example</title>
    <link
      rel="stylesheet"
      href="https://glide-ui.flingit.run/latest/index.css"
    />
    <!-- Optional: apply a theme -->
    <!-- <link rel="stylesheet" href="https://glide-ui.flingit.run/latest/industrial.css" /> -->
    <script type="importmap">
      {
        "imports": {
          "react": "https://esm.sh/react@19",
          "react-dom": "https://esm.sh/react-dom@19",
          "react-dom/client": "https://esm.sh/react-dom@19/client",
          "react/jsx-runtime": "https://esm.sh/react@19/jsx-runtime",
          "react-router": "https://esm.sh/react-router@7",
          "maplibre-gl": "https://esm.sh/maplibre-gl@5?bundle",
          "@glide/glide-ui/": "https://glide-ui.flingit.run/latest/"
        }
      }
    </script>
    <script src="https://unpkg.com/@babel/standalone/babel.min.js"></script>
    <script>
      Babel.registerPreset("tsx", {
        presets: [
          [
            Babel.availablePresets.typescript,
            { isTSX: true, allExtensions: true },
          ],
          [Babel.availablePresets.react, {}],
        ],
      });
    </script>
  </head>
  <body>
    <div id="root"></div>
    <script type="text/babel" data-type="module" data-presets="tsx">
      import React, { useState } from "react";
      import { createRoot } from "react-dom/client";
      import { Button } from "@glide/glide-ui/button";

      // Full TypeScript supported — interfaces, generics, import type all work
      interface CounterProps {
        initial?: number;
      }

      function Counter({ initial = 0 }: CounterProps) {
        const [count, setCount] = useState<number>(initial);
        return (
          <Button onClick={() => setCount((c) => c + 1)}>
            Clicked {count} times
          </Button>
        );
      }

      createRoot(document.getElementById("root")).render(<Counter />);
    </script>
  </body>
</html>
```

### CDN URLs

**Latest version (always points to the most recent release):**

```
https://glide-ui.flingit.run/latest/glide-ui.js        # JS bundle (ES module)
https://glide-ui.flingit.run/latest/index.css           # Base CSS
https://glide-ui.flingit.run/latest/industrial.css      # Industrial theme
https://glide-ui.flingit.run/latest/smooth.css          # Smooth theme
```

**Pinned version (recommended for production):**

```
https://glide-ui.flingit.run/v0.0.372/glide-ui.js
https://glide-ui.flingit.run/v0.0.372/index.css
https://glide-ui.flingit.run/v0.0.372/industrial.css
https://glide-ui.flingit.run/v0.0.372/smooth.css
```

### Themes

Load a theme by adding a `<link>` tag after the base CSS:

```html
<link rel="stylesheet" href="https://glide-ui.flingit.run/latest/index.css" />
<link
  rel="stylesheet"
  href="https://glide-ui.flingit.run/latest/industrial.css"
/>
```

### External Dependencies

The CDN bundle externalizes React, React DOM, React Router, and MapLibre GL. Load them via [esm.sh](https://esm.sh) import maps as shown in the quick start example above.

### Canary Versions

Every pull request publishes a canary build to the CDN. The canary version format is `v{version}-canary.{sha7}` (e.g., `v0.0.372-canary.abc1234`). Check the PR comments for exact URLs.

### Dashboard

View published versions at the [Fling CDN dashboard](https://glide-ui.flingit.run).

## Getting Started

### Import the CSS

To use the Glide UI components, you need to import the CSS file in your application's entry point:

```tsx
// In your main app file (e.g., App.tsx, main.tsx, or index.tsx)
import "@glide/glide-ui/index.css";
```

This CSS file includes:

- All Tailwind CSS utilities
- Custom theme variables and colors
- Typography styles
- Component-specific animations
- Light/dark mode support

### Development

```bash
npm install
npm run dev        # Start development server
npm run storybook  # View component documentation
```

### Build

```bash
npm run build     # Build the library
npm run preview   # Preview the build
npm run lint      # Run linting
```

### Testing

```bash
./scripts/test                    # Run tests via script (auto-installs Playwright browsers if needed)
./scripts/test <pattern>          # Run tests matching a specific pattern (e.g., "./scripts/test button" to run button tests)
./scripts/test <args...>         # Pass any arguments through to vitest (e.g., "./scripts/test --reporter=verbose button")

npm run test:ui           # Run tests with UI
npm run test:coverage    # Run tests with coverage
npm run test:ssr         # Run SSR-specific tests
```

Tests are configured to run in parallel across all available CPU cores for maximum performance. The test suite includes:

- **Unit tests** - Component tests running in jsdom environment
- **SSR tests** - Server-side rendering tests in Node environment
- **Storybook tests** - Browser-based visual regression tests

## Quick Example

```tsx
// Import the CSS (typically in your app's entry point)
import "@glide/glide-ui/index.css";

// Import components as needed
import { Button } from "@glide/glide-ui/button";
import { Input } from "@glide/glide-ui/input";
import { Form } from "@glide/glide-ui/form";

function MyForm() {
  return (
    <Form onSubmit={handleSubmit}>
      <Input label="Email" type="email" required />
      <Button type="submit">Submit</Button>
    </Form>
  );
}
```

## Playground

Try out the Glide UI components and AI screen generation in our interactive playground:

🌐 **[Live Playground](https://glide-ui-785571128567.us-central1.run.app/)**

The playground allows you to:

- Generate complete React screens using natural language prompts
- See real-time code generation with Claude AI
- Explore component usage in a Remix environment
- Copy generated code for your own projects

See the [sandbox README](sandbox/README.md) for more details on running the playground locally.

## Stack

- **React 19** + **TypeScript** - Type-safe components
- **Tailwind CSS v4** - Utility-first styling
- **Radix UI** - Accessible component primitives
- **Vite** - Lightning-fast build tooling
- **Storybook** - Component documentation and testing

## Features

- ✅ **Fully Accessible** - WCAG 2.1 AA compliant
- 📱 **Mobile Responsive** - Touch-friendly with mobile-first design
- 🎨 **Customizable** - Tailwind-based theming with accent colors
- 🚀 **Tree-shakeable** - Import only what you need
- 📖 **Well Documented** - Comprehensive docs and examples
- 🧪 **Thoroughly Tested** - Unit tests with Vitest
- 🌐 **SSR Ready** - Full server-side rendering support for Next.js, Remix, and other SSR frameworks
- 🧭 **Accessible Page Headers** - `ScreenTitle` requires an explicit `title` prop for clear page context

## Publishing

This library is automatically published when the version in `package.json` is updated and merged to the `main` branch:

- **Google Artifact Registry (GAR)** — npm package for `@glide/glide-ui`
- **Fling CDN** — JS + CSS bundles at `glide-ui.flingit.run` for `<script>`/`<link>` tag usage

Both channels publish in parallel. Pull requests also publish canary builds to both GAR and the CDN.
