# mini-lit Package Reference

Lightweight Lit components with shadcn-inspired theming and Tailwind CSS v4 integration.
Live demo: https://minilit.mariozechner.at

## Important: How to Use This Documentation with LLMs

**Before using any component, instruct your LLM to read the source files** to fully understand:
- The exact props interface and TypeScript types
- How components handle different prop combinations
- Available variants, sizes, and options
- Internal implementation and rendering logic
- Function overloads and shorthand syntaxes

### Files to Read for Component Implementation:

**Functional Components** (stateless, return TemplateResult):
- `src/Alert.ts` - Alert with title and description
- `src/Badge.ts` - Status indicators with variants
- `src/Button.ts` - Buttons with loading, variants, sizes
- `src/Card.ts` - Cards with header, content, footer sections
- `src/Checkbox.ts` - Checkbox with label and indeterminate state
- `src/Dialog.ts` - Modal dialogs with header/footer
- `src/Input.ts` - Text inputs with validation
- `src/Label.ts` - Form labels with required indicator
- `src/Progress.ts` - Progress bars
- `src/Select.ts` - Dropdowns with groups and icons
- `src/Separator.ts` - Visual dividers
- `src/Switch.ts` - Toggle switches
- `src/Textarea.ts` - Multi-line text input
- `src/Diff.ts` - Code difference viewer
- `src/FileButton.ts` - File upload button
- `src/CopyButton.ts` - Copy to clipboard button
- `src/DownloadButton.ts` - Download file button

**Custom Elements** (stateful LitElement classes):
- `src/CodeBlock.ts` - Syntax highlighted code (`<code-block>`)
- `src/MarkdownBlock.ts` - Markdown with math (`<markdown-block>`)
- `src/ThemeToggle.ts` - Dark/light switcher (`<theme-toggle>`)
- `src/LanguageSelector.ts` - i18n language picker (`<language-selector>`)
- `src/SplitPanel.ts` - Resizable panels (`<split-panel>`)
- `src/ModeToggle.ts` - Mode switcher (`<mode-toggle>`)
- `src/PreviewCode.ts` - Preview/code toggle (`<preview-code>`)
- `src/Sidebar.ts` - Collapsible sidebar (`<sidebar>`)

**Core Systems**:
- `src/mini.ts` - Core utilities (fc, createState, refs, types)
- `src/i18n.ts` - Internationalization system
- `src/icons.ts` - Icon rendering utilities
- `src/index.ts` - Main exports

## Quick Setup

```bash
npm install lit @mariozechner/mini-lit
```

Configure Tailwind CSS v4:
```css
/* src/app.css */
@import "@mariozechner/mini-lit/styles/themes/default.css";
@source "../node_modules/@mariozechner/mini-lit/dist";
@import "tailwindcss";
```

**Available theme files:**
- `@mariozechner/mini-lit/styles/themes/default.css` - Clean modern theme
- `@mariozechner/mini-lit/styles/themes/claude.css` - Claude-inspired theme

## Component Architecture

mini-lit provides two component types:

1. **Functional Components**: Stateless, return TemplateResult
   - Alert, Badge, Button, Card, Checkbox, Dialog, Input, Label, Progress, Select, Separator, Switch, Textarea

2. **Custom Elements**: Stateful LitElement classes with HTML tags
   - `<code-block>`, `<markdown-block>`, `<theme-toggle>`, `<language-selector>`, `<split-panel>`, `<mode-toggle>`, `<preview-code>`

## Core Components Usage
## Tree-Shaking & Bundle Optimization

**CRITICAL**: The root index (`@mariozechner/mini-lit`) now **ONLY** exports core utilities (component system, i18n, and icons). Individual components are **NOT** exported from the root to enforce optimal tree-shaking.

### What's Exported from Root Index
```typescript
// ✅ Core utilities available from root
import {
  // Component system
  ComponentLitBase, createComponent, defineComponent, styleComponent,
  // i18n system
  i18n, setTranslations, setLanguage, getCurrentLanguage,
  defaultEnglish, defaultGerman,
  // Icons
  icon
} from "@mariozechner/mini-lit";
```

### Component Imports (Required)
```typescript
// ✅ MUST import components from their individual files
import { Button } from "@mariozechner/mini-lit/dist/Button.js";
import { Card } from "@mariozechner/mini-lit/dist/Card.js";
import { Input } from "@mariozechner/mini-lit/dist/Input.js";
import "@mariozechner/mini-lit/dist/ThemeToggle.js";

// ❌ Components are NOT exported from root
import { Button, Card } from "@mariozechner/mini-lit"; // Won't work!
```

**Bundle Size**:
- Direct component imports: ~50-100KB (only what you use)
- Core utilities from root: ~20KB

**Available Paths**:
- Functional components: `/dist/Button.js`, `/dist/Card.js`, `/dist/Input.js`, `/dist/Select.js`, `/dist/Checkbox.js`, `/dist/Switch.js`, `/dist/Textarea.js`, `/dist/Label.js`, `/dist/Badge.js`, `/dist/Alert.js`, `/dist/Progress.js`, `/dist/Separator.js`, `/dist/Dialog.js`, `/dist/CopyButton.js`, `/dist/DownloadButton.js`, `/dist/FileButton.js`, `/dist/Diff.js`
- Custom elements: `/dist/ThemeToggle.js`, `/dist/CodeBlock.js`, `/dist/MarkdownBlock.js`, `/dist/LanguageSelector.js`, `/dist/SplitPanel.js`, `/dist/ModeToggle.js`, `/dist/PreviewCode.js`, `/dist/Sidebar.js`
- Core utilities: `/dist/mini.js` (fc, createState, refs), `/dist/i18n.js`, `/dist/icons.js`



### Button
```typescript
import { Button } from "@mariozechner/mini-lit/dist/Button.js";

// Object syntax
Button({
  variant: "default", // "default" | "destructive" | "outline" | "secondary" | "ghost" | "link"
  size: "md",         // "sm" | "md" | "lg" | "icon"
  disabled: false,
  loading: false,
  onClick: (e) => console.log("clicked"),
  children: "Click me"
})

// Shorthand syntax
Button("Click me", "primary", "sm")
```

### Card
```typescript
import { Card, CardHeader, CardTitle, CardDescription, CardContent, CardFooter } from "@mariozechner/mini-lit/dist/Card.js";

Card({
  hoverable: true,
  children: html`
    ${CardHeader(html`
      ${CardTitle("Card Title")}
      ${CardDescription("Card description")}
    `)}
    ${CardContent("Main content here")}
    ${CardFooter("Footer content")}
  `
})
```

### Input
```typescript
import { Input } from "@mariozechner/mini-lit/dist/Input.js";

Input({
  type: "text",      // "text" | "email" | "password" | "number" | "url" | "tel" | "search" | "date"
  size: "md",        // "sm" | "md" | "lg"
  value: "",
  placeholder: "Enter text",
  label: "Name",
  error: "",
  disabled: false,
  required: true,
  onInput: (e) => console.log(e.target.value),
  onChange: (e) => console.log("changed")
})
```

### Select
```typescript
import { Select } from "@mariozechner/mini-lit/dist/Select.js";

Select({
  value: "option1",
  placeholder: "Select an option",
  options: [
    { value: "option1", label: "Option 1" },
    { value: "option2", label: "Option 2", disabled: true },
    { value: "option3", label: "Option 3", icon: icon(Star) }
  ],
  // Or grouped options:
  options: [
    {
      label: "Group 1",
      options: [
        { value: "a", label: "Item A" },
        { value: "b", label: "Item B" }
      ]
    }
  ],
  onChange: (value) => console.log(value),
  size: "md",         // "sm" | "md" | "lg"
  variant: "default", // "default" | "ghost" | "outline"
  fitContent: false,  // Auto-width to content
  width: "180px"
})
```

### Checkbox & Switch
```typescript
import { Checkbox } from "@mariozechner/mini-lit/dist/Checkbox.js";
import { Switch } from "@mariozechner/mini-lit/dist/Switch.js";

Checkbox({
  checked: false,
  indeterminate: false,
  label: "Accept terms",
  disabled: false,
  onChange: (checked) => console.log(checked)
})

Switch({
  checked: false,
  label: "Enable notifications",
  onChange: (checked) => console.log(checked)
})
```

### Dialog
```typescript
import { Dialog, DialogContent, DialogHeader, DialogFooter } from "@mariozechner/mini-lit/dist/Dialog.js";

Dialog({
  isOpen: true,
  onClose: () => console.log("closed"),
  width: "600px",
  height: "auto",
  children: html`
    ${DialogContent(html`
      ${DialogHeader({
        title: "Dialog Title",
        description: "Dialog description"
      })}
      <div>Main content</div>
      ${DialogFooter(html`
        ${Button({ children: "Cancel" })}
        ${Button({ variant: "primary", children: "Confirm" })}
      `)}
    `)}
  `
})
```

### Alert & Badge
```typescript
import { Alert, AlertTitle, AlertDescription } from "@mariozechner/mini-lit/dist/Alert.js";
import { Badge } from "@mariozechner/mini-lit/dist/Badge.js";

Alert({
  variant: "default", // "default" | "destructive"
  children: html`
    ${AlertTitle("Alert Title")}
    ${AlertDescription("Alert message here")}
  `
})

Badge({
  variant: "default", // "default" | "secondary" | "destructive" | "outline"
  children: "New"
})
```

### Progress
```typescript
import { Progress } from "@mariozechner/mini-lit/dist/Progress.js";

Progress({
  value: 50,
  max: 100,
  className: "w-full"
})
```

### Separator
```typescript
import { Separator } from "@mariozechner/mini-lit/dist/Separator.js";

Separator({
  orientation: "horizontal", // "horizontal" | "vertical"
  decorative: true
})
```

## Custom Elements

### CodeBlock
```html
<code-block
  language="typescript"
  code="${btoa('const greeting = "Hello";')}"
  showLineNumbers="${true}"
  showCopyButton="${true}">
</code-block>
```

### MarkdownBlock
```html
<markdown-block
  content="# Heading\nSupports **markdown** with $LaTeX$ math"
  isThinking="${false}"
  escapeHtml="${true}">
</markdown-block>
```

### ThemeToggle
```html
<!-- Automatic dark/light mode switcher -->
<theme-toggle></theme-toggle>
```

### LanguageSelector
```html
<!-- Dropdown for language switching -->
<language-selector></language-selector>
```

### SplitPanel
```html
<split-panel
  .leftPanel=${html`<div>Left content</div>`}
  .rightPanel=${html`<div>Right content</div>`}
  initialSplit="50"
  minSize="200"
  hideRight="${false}"
  vertical="${false}">
</split-panel>
```

### ModeToggle
```html
<mode-toggle
  .modes=${["Preview", "Code"]}
  selectedIndex="0"
  @mode-change=${(e) => console.log(e.detail)}>
</mode-toggle>
```

## Icons

```typescript
import { icon } from "@mariozechner/mini-lit/dist/icons.js";
import { Send, Settings, User } from "lucide";

// Render icon with size
icon(Send)           // Default size
icon(Send, "sm")     // 16px
icon(Send, "md")     // 20px
icon(Send, "lg")     // 24px
icon(Send, "xl")     // 28px

// In component
Button({
  children: html`${icon(Send, "sm")} Send Message`
})
```

## Internationalization (i18n)

**Read `src/i18n.ts` for complete implementation details.**

The i18n system provides:
- Type-safe message keys with TypeScript
- Support for parameterized messages (functions)
- Browser language detection
- localStorage persistence
- Default English and German translations

### Setup TypeScript Interface
```typescript
// Extend with your messages
declare module "@mariozechner/mini-lit" {
  interface i18nMessages extends MiniLitRequiredMessages {
    Welcome: string;
    Settings: string;
    itemCount: (count: number) => string;
    greeting: (name: string, time: string) => string;
  }
}
```

### Configure Translations
```typescript
import { setTranslations, defaultEnglish, defaultGerman } from "@mariozechner/mini-lit";

setTranslations({
  en: {
    ...defaultEnglish, // Required mini-lit messages
    Welcome: "Welcome",
    Settings: "Settings",
    itemCount: (count) => count === 1 ? "1 item" : `${count} items`,
    greeting: (name, time) => `Good ${time}, ${name}!`
  },
  de: {
    ...defaultGerman,
    Welcome: "Willkommen",
    Settings: "Einstellungen",
    itemCount: (count) => count === 1 ? "1 Artikel" : `${count} Artikel`,
    greeting: (name, time) => `Guten ${time}, ${name}!`
  }
});
```

### Use in Components
```typescript
import { i18n, getCurrentLanguage, setLanguage } from "@mariozechner/mini-lit";

// Simple strings
${i18n("Welcome")}

// Functions with parameters
${i18n("itemCount")(5)}              // "5 items"
${i18n("greeting")("Alice", "morning")} // "Good morning, Alice!"

// Language management
getCurrentLanguage()  // Returns current language code
setLanguage("de")     // Switch language and reload page
```

## Utility Components

### FileButton
```typescript
import { FileButton } from "@mariozechner/mini-lit/dist/FileButton.js";

FileButton({
  accept: ".pdf,.doc",
  multiple: true,
  maxFileSize: 5 * 1024 * 1024, // 5MB
  onFilesSelected: (files) => console.log(files),
  children: "Upload Files"
})
```

### CopyButton
```typescript
import { CopyButton } from "@mariozechner/mini-lit/dist/CopyButton.js";

CopyButton({
  text: "Text to copy",
  onCopy: () => console.log("Copied!"),
  children: "Copy"
})
```

### DownloadButton
```typescript
import { DownloadButton } from "@mariozechner/mini-lit/dist/DownloadButton.js";

DownloadButton({
  data: "File content here",
  filename: "output.txt",
  mimeType: "text/plain",
  children: "Download"
})
```

### Diff Viewer
```typescript
import { Diff } from "@mariozechner/mini-lit/dist/Diff.js";

Diff({
  oldText: "Original text",
  newText: "Modified text",
  title: "Changes"
})
```

## mini.ts Core Utilities

### Functional Component Helper
```typescript
import { fc, html, type TemplateResult } from "@mariozechner/mini-lit/dist/mini.js";

const MyComponent = fc<{ text: string }>(({ text }) => {
  return html`<div>${text}</div>`;
});
```

### Reactive State
```typescript
import { createState } from "@mariozechner/mini-lit/dist/mini.js";

const state = createState({
  count: 0,
  name: ""
});

// Subscribe to changes
const unsubscribe = state.__subscribe(() => {
  console.log("State changed");
});

// Update state (triggers subscribers)
state.count++;
```

### Refs
```typescript
import { createRef, ref } from "@mariozechner/mini-lit/dist/mini.js";

const inputRef = createRef<HTMLInputElement>();

html`
  <input ${ref(inputRef)} />
  <button @click=${() => console.log(inputRef.value?.value)}>
    Log Value
  </button>
`
```

## Theming

### Available Themes
- `default.css` - Clean modern theme
- `claude.css` - Claude-inspired theme

### Dark Mode
```javascript
// Toggle programmatically
document.documentElement.classList.toggle("dark");

// Or use built-in component
<theme-toggle></theme-toggle>
```

### Custom Themes
Create custom themes using CSS variables:
```css
:root {
  --background: 0 0% 100%;
  --foreground: 222.2 84% 4.9%;
  --primary: 221.2 83.2% 53.3%;
  --primary-foreground: 210 40% 98%;
  /* ... other variables */
}

.dark {
  --background: 222.2 84% 4.9%;
  --foreground: 210 40% 98%;
  /* ... dark mode overrides */
}
```

## Component Props Interface

### BaseComponentProps
All components accept:
- `className?: string` - Additional CSS classes
- `children?: TemplateResult | string | number`

### ComponentPropsWithoutChildren
For components without children:
- `className?: string`

## Complete Example

```typescript
import { html, render } from "lit";
import { Button } from "@mariozechner/mini-lit/dist/Button.js";
import { Card, CardContent } from "@mariozechner/mini-lit/dist/Card.js";
import { Input } from "@mariozechner/mini-lit/dist/Input.js";
import { Select } from "@mariozechner/mini-lit/dist/Select.js";
import { Switch } from "@mariozechner/mini-lit/dist/Switch.js";
import { icon, i18n, setTranslations, defaultEnglish } from "@mariozechner/mini-lit";
import "@mariozechner/mini-lit/dist/ThemeToggle.js";
import { Send } from "lucide";
import "./app.css";

// Setup i18n
setTranslations({
  en: {
    ...defaultEnglish,
    Welcome: "Welcome to mini-lit"
  }
});

// State management
const state = {
  name: "",
  theme: "light",
  notifications: true
};

const App = () => html`
  <div class="p-8 bg-background min-h-screen">
    <theme-toggle class="fixed top-4 right-4"></theme-toggle>

    ${Card({
      children: html`
        ${CardContent(html`
          <h1 class="text-2xl font-bold mb-4">${i18n("Welcome")}</h1>

          ${Input({
            label: "Name",
            value: state.name,
            onInput: (e) => state.name = e.target.value
          })}

          ${Select({
            value: state.theme,
            options: [
              { value: "light", label: "Light Theme" },
              { value: "dark", label: "Dark Theme" }
            ],
            onChange: (value) => state.theme = value
          })}

          ${Switch({
            checked: state.notifications,
            label: "Enable notifications",
            onChange: (checked) => state.notifications = checked
          })}

          ${Button({
            variant: "primary",
            children: html`${icon(Send, "sm")} Submit`,
            onClick: () => console.log(state)
          })}
        `)}
      `
    })}
  </div>
`;

render(App(), document.body);
```

## TypeScript Support

All components are fully typed. Import types:
```typescript
import type {
  ButtonProps, ButtonVariant, ButtonSize,
  InputProps, InputType, InputSize,
  SelectOption, SelectGroup,
  AlertProps, AlertVariant,
  BaseComponentProps,
  TemplateResult
} from "@mariozechner/mini-lit";
```

## Package Exports

- Main: `@mariozechner/mini-lit`
- Styles: `@mariozechner/mini-lit/styles/*`
- Components: Imported from main export

## Performance Tips

1. Use functional components for stateless UI
2. Use custom elements only when internal state is needed
3. Batch DOM updates with Lit's rendering system
4. Leverage reactive state for efficient updates
5. Use refs sparingly for direct DOM access

## Browser Support

Requires modern browsers with:
- ES2020+ support
- Web Components support
- CSS custom properties
- CSS grid and flexbox

## Dependencies

- lit: ^3.3.1 (peer dependency)
- highlight.js: Code syntax highlighting
- marked: Markdown parsing
- katex: LaTeX math rendering
- lucide: Icon library
- diff: Text diffing

## License

MIT
