commit 7afdd6601b8bde7a47f9076fc46ff09e368a39f7 Author: Zhongwei Li Date: Sun Nov 30 09:05:04 2025 +0800 Initial commit diff --git a/.claude-plugin/plugin.json b/.claude-plugin/plugin.json new file mode 100644 index 0000000..19e1056 --- /dev/null +++ b/.claude-plugin/plugin.json @@ -0,0 +1,11 @@ +{ + "name": "vuer-uikit", + "description": "Complete documentation for Vuer UIKit React component library including 38 UI components, Dial system for control panels, style guides, and layout patterns", + "version": "0.1.0", + "author": { + "name": "Ge Yang" + }, + "skills": [ + "./" + ] +} \ No newline at end of file diff --git a/COMPLETION_STATUS.md b/COMPLETION_STATUS.md new file mode 100644 index 0000000..ace1e73 --- /dev/null +++ b/COMPLETION_STATUS.md @@ -0,0 +1,142 @@ +# Vuer UIKit Documentation Fetch - Completion Status + +## Summary + +**Total Pages:** 64 +**Fetched and Saved:** 18 pages +**Fetched (Content Ready, Needs Saving):** 11 pages +**Remaining to Fetch:** 35 pages + +## Completed and Saved (18 pages) + +### Guides (2/2) +- ✅ guides/introduction.md +- ✅ guides/getting-started.md + +### Style Guide (4/4) +- ✅ style-guide/colors.md +- ✅ style-guide/font.md +- ✅ style-guide/icons.md +- ✅ style-guide/layout.md + +### Form Inputs (4/4) +- ✅ form-inputs/input.md +- ✅ form-inputs/number-inputs.md +- ✅ form-inputs/playground.md +- ✅ form-inputs/specialized-inputs.md + +### Dial System (2/9) +- ✅ dial/overview.md +- ✅ dial/getting-started.md + +### Components (3/38) +- ✅ components/button.md +- ✅ components/avatar.md +- ✅ components/badge.md + +### Other (1/2) +- ✅ other/hooks.md + +## Content Fetched, Ready to Save (11 pages) + +These pages have been successfully fetched via WebFetch and their content is available in the conversation history. They just need to be written to files: + +### Dial System (7 pages) +- dial/tutorial.md +- dial/input-types.md +- dial/type-inheritance.md +- dial/cli-details.md +- dial/testing.md +- dial/controlled-dials.md +- dial/api-notes.md + +### Menu Tool Layouts (3 pages) +- menu-tool-layouts/dock-layout.md +- menu-tool-layouts/liquid-float-layout.md +- menu-tool-layouts/toolbar.md + +### Other (1 page) +- other/test-codeblock.md + +## Remaining to Fetch (35 component pages) + +### Components List +1. components/card.md +2. components/checkbox.md +3. components/collapsible.md +4. components/cursor-display.md +5. components/drag-selectable.md +6. components/drawer.md +7. components/dropdown.md +8. components/layout.md +9. components/modal.md +10. components/navbar.md +11. components/navigation.md +12. components/pagination.md +13. components/popover.md +14. components/preview.md +15. components/progress.md +16. components/radio-group.md +17. components/select.md +18. components/sheet.md +19. components/sidebar.md +20. components/simple-tree-view.md +21. components/slider.md +22. components/spinner.md +23. components/switch.md +24. components/sync-scroll.md +25. components/table.md +26. components/tabs.md +27. components/textarea.md +28. components/toast.md +29. components/toggle.md +30. components/toggle-buttons.md +31. components/toggle-group.md +32. components/tooltip.md +33. components/tree-view.md +34. components/version-badge.md +35. components/waterfall.md + +## Next Steps + +### Immediate (Save Fetched Content) +The following files are ready to be saved from the WebFetch results in this conversation. Run Write operations for each: + +1. Dial System files (7 files) - Content available in WebFetch results +2. Menu Tool Layouts files (3 files) - Content available in WebFetch results +3. test-codeblock.md (1 file) - Content available in WebFetch results + +### Subsequent (Fetch Remaining) +After saving the ready content, fetch the remaining 35 component pages using: + +```bash +# For each component, use WebFetch with pattern: +WebFetch URL: https://uikit.vuer.ai/components/{component-name}/ +Prompt: Extract the main documentation content about the {Component} component. Include all text, usage examples, props documentation, code snippets, and explanations. Remove navigation elements, headers, and footers. Format as markdown. +``` + +Components can be fetched in batches of 5-10 for efficiency. + +## URLs Reference + +Base URL: `https://uikit.vuer.ai/` + +Pattern for components: `https://uikit.vuer.ai/components/{component-name}/` +Pattern for other pages: `https://uikit.vuer.ai/{category}/{page-name}/` + +## File Locations + +All markdown files are saved to: +`/Users/ge/fortyfive/awesome-skills/skills/vuer-uikit/docs/` + +Directory structure: +``` +docs/ +├── guides/ +├── style-guide/ +├── form-inputs/ +├── dial/ +├── menu-tool-layouts/ +├── components/ +└── other/ +``` diff --git a/README.md b/README.md new file mode 100644 index 0000000..416171a --- /dev/null +++ b/README.md @@ -0,0 +1,3 @@ +# vuer-uikit + +Complete documentation for Vuer UIKit React component library including 38 UI components, Dial system for control panels, style guides, and layout patterns diff --git a/SKILL.md b/SKILL.md new file mode 100644 index 0000000..ececd67 --- /dev/null +++ b/SKILL.md @@ -0,0 +1,84 @@ +--- +name: vuer-uikit +description: Expert knowledge of Vuer UIKit, a React component library for building interactive 3D and UI applications with 38 components and a powerful Dial system +--- + +# Vuer UIKit Documentation Skill + +Expert knowledge of Vuer UIKit, a React component library for building interactive 3D and UI applications. + +## What is Vuer UIKit? + +Vuer UIKit is a comprehensive React component library designed for building modern user interfaces, particularly for 3D visualization and interactive applications. It provides a rich set of components including forms, layouts, data displays, and a powerful Dial system for creating control panels. + +## Documentation Coverage + +This skill includes complete documentation for: + +### Getting Started +- Introduction and overview +- Installation and setup guide + +### Style Guide +- Color system and theming +- Typography and fonts +- Icon library +- Layout principles + +### Form Inputs +- Standard input components +- Number inputs with specialized controls +- Interactive playground +- Specialized input types + +### Dial System +The Dial system is a powerful feature for creating control panels: +- Overview and concepts +- Getting started guide +- Step-by-step tutorial +- Comprehensive input type reference +- Type inheritance patterns +- CLI tooling reference +- Testing strategies +- Controlled dial patterns +- API design notes + +### Menu & Tool Layouts +- Dock layout for panels +- Liquid float layout for dynamic positioning +- Toolbar components + +### Components (38 total) +Complete documentation for all UI components including: +- Navigation: Navbar, Navigation, Sidebar, Tabs +- Data Display: Avatar, Badge, Card, Table, Waterfall +- Overlays: Modal, Drawer, Popover, Sheet, Toast, Tooltip +- Inputs: Button, Checkbox, Radio Group, Select, Slider, Switch, Textarea, Toggle components +- Feedback: Progress, Spinner, Version Badge +- Advanced: Tree View, Collapsible, Cursor Display, Drag Selectable, Sync Scroll, Preview + +### Hooks +Custom React hooks for common patterns + +## Usage + +When helping with Vuer UIKit: +1. Reference the specific component documentation in `docs/components/` +2. For Dial-related questions, check the comprehensive Dial system docs in `docs/dial/` +3. For styling and theming, refer to `docs/style-guide/` +4. For layout patterns, see `docs/menu-tool-layouts/` + +## Official Resources + +- Documentation Site: https://uikit.vuer.ai/ +- GitHub Repository: https://github.com/vuer-ai/vuer-uikit + +## Skills + +This skill helps you: +- Build UIs with Vuer UIKit components +- Create control panels using the Dial system +- Apply consistent styling and theming +- Implement complex layouts and interactions +- Use specialized form inputs and controls +- Test Dial-annotated components diff --git a/docs/README.md b/docs/README.md new file mode 100644 index 0000000..c844c19 --- /dev/null +++ b/docs/README.md @@ -0,0 +1,105 @@ +# Vuer UIKit Documentation + +This directory contains the complete documentation for Vuer UIKit, fetched from https://uikit.vuer.ai/ + +## Documentation Structure + +### Guides (2/2 complete) +- [Introduction](guides/introduction.md) - Overview and quick start +- [Getting Started](guides/getting-started.md) - Installation and setup + +### Style Guide (4/4 complete) +- [Colors](style-guide/colors.md) - Color system and variables +- [Font](style-guide/font.md) - Typography scale +- [Icons](style-guide/icons.md) - Icon system using Lucide +- [Layout](style-guide/layout.md) - Spacing and border radius + +### Form Inputs (4/4 complete) +- [Input](form-inputs/input.md) - Basic input component +- [Number Inputs](form-inputs/number-inputs.md) - Numeric inputs with drag functionality +- [Playground](form-inputs/playground.md) - Interactive playground +- [Specialized Inputs](form-inputs/specialized-inputs.md) - Unit-specific inputs (cm, rad, vector3, etc.) + +### Dial System (2/9 fetched) +- [Overview](dial/overview.md) - Dial system introduction +- [Getting Started](dial/getting-started.md) - Installation and basic workflow +- Tutorial - *Fetched, needs saving* +- Input Types - *Fetched, needs saving* +- Type Inheritance - *Fetched, needs saving* +- CLI Reference - *Fetched, needs saving* +- Testing - *Fetched, needs saving* +- Controlled Dials - *Fetched, needs saving* +- API Notes - *Fetched, needs saving* + +### Menu Tool Layouts (0/3 - fetched, needs saving) +- Dock Layout - *Fetched, needs saving* +- Liquid Float Layout - *Fetched, needs saving* +- Toolbar - *Fetched, needs saving* + +### Components (3/38 - 3 fetched, 35 remaining) +#### Fetched (needs saving): +- Avatar - *Fetched, needs saving* +- Badge - *Fetched, needs saving* +- Button - *Fetched, needs saving* + +#### Remaining to fetch (35 components): +- Card +- Checkbox +- Collapsible +- Cursor Display +- Drag Selectable +- Drawer +- Dropdown +- Layout +- Modal +- Navbar +- Navigation +- Pagination +- Popover +- Preview +- Progress +- Radio Group +- Select +- Sheet +- Sidebar +- Simple Tree View +- Slider +- Spinner +- Switch +- Sync Scroll +- Table +- Tabs +- Textarea +- Toast +- Toggle +- Toggle Buttons +- Toggle Group +- Tooltip +- Tree View +- Version Badge +- Waterfall + +### Other (1/2 complete) +- [Hooks](other/hooks.md) - React hooks documentation +- Test Codeblock - *Fetched, needs saving* + +## Fetch Status Summary + +**Completed and Saved:** 15 pages +**Fetched (needs saving):** 14 pages +**Remaining to fetch:** 35 pages +**Total:** 64 pages + +## Next Steps + +To complete the documentation: + +1. Save the 14 already-fetched pages (see list above) +2. Fetch the remaining 35 component pages +3. Verify all links and cross-references + +## Source + +All documentation fetched from: https://uikit.vuer.ai/ +Version: v0.0.117 +Dial CLI Version: v0.0.22 diff --git a/docs/components/avatar.md b/docs/components/avatar.md new file mode 100644 index 0000000..5526cf2 --- /dev/null +++ b/docs/components/avatar.md @@ -0,0 +1,77 @@ +# Avatar Component Documentation + +## Overview + +The Avatar component presents a circular image element designed for representing users, with built-in fallback functionality. It extends Radix UI's Avatar primitive and includes server-side rendering support plus enhanced features for grouping multiple avatars. + +## Component Parts + +### Avatar (Root) +The main container for displaying user avatars. + +**Props:** +- `className` (string): Additional CSS classes +- `children` (ReactNode): AvatarImage and AvatarFallback components +- Supports all Radix UI Avatar.Root props + +### AvatarImage +Renders the user's profile image with automatic fallback handling. + +**Props:** +- `src` (string): Image source URL +- `alt` (string): Alternative text for accessibility +- `className` (string): Custom CSS classes +- Inherits all Radix UI Avatar.Image props + +### AvatarFallback +Shows fallback content when the image fails to load. + +**Props:** +- `className` (string): Custom styling +- `children` (ReactNode): Fallback content, typically initials +- Supports all Radix UI Avatar.Fallback props + +### AvatarGroup +Groups multiple avatars in a stacked arrangement with configurable spacing. + +**Props:** +- `children` (ReactNode): Avatar components to display +- `className` (string): Custom CSS classes +- `spacing` ("tight" | "normal" | "loose"): Controls avatar spacing +- `max` (number): Maximum avatars shown before displaying "+N" indicator + +**Spacing Options:** +- **tight**: Closest together (`-space-x-1.5`) +- **normal**: Default spacing (`-space-x-1`) +- **loose**: Most space between (`-space-x-0.45`) + +## Usage Examples + +### Basic Avatar +```jsx + + + CN + +``` + +### Custom Sizes +```jsx +
+ + + CN + + + + CN + + + + CN + +
+``` + +### Avatar Groups with Spacing Variants +Groups can implement tight, normal, or loose spacing configurations by adjusting the `spacing` prop on the `AvatarGroup` component. diff --git a/docs/components/badge.md b/docs/components/badge.md new file mode 100644 index 0000000..a3743ca --- /dev/null +++ b/docs/components/badge.md @@ -0,0 +1,68 @@ +# Badge Component Documentation + +## Overview + +The Badge component displays a badge or badge-like visual element. It extends standard span functionality with customizable variants and shapes. + +## Type Definition + +```typescript +interface BadgeProps extends ComponentProps<"span">, VariantProps { + asChild?: boolean; + variant?: "default" | "secondary" | "destructive" | "success" | "warning" | "accent"; + type?: "default" | "circle" | "dot"; +} +``` + +## Properties + +| Property | Type | Default | Purpose | +|----------|------|---------|---------| +| `variant` | `'default' \| 'secondary' \| 'destructive' \| 'success' \| 'warning' \| 'accent'` | `'default'` | Determines the visual styling | +| `type` | `'default' \| 'circle' \| 'dot'` | `'default'` | Controls shape and layout presentation | +| `asChild` | `boolean` | `false` | Enables `Slot` rendering for child element styling | +| span props | `ComponentProps<'span'>` | — | All native HTML span attributes supported | + +## Basic Examples + +Simple badge variants: +```jsx +Default +Deployed +3 + +``` + +## Usage Patterns + +**Variant showcase:** +```jsx +Badge +Secondary +Destructive +Success +warning +``` + +**Circular badge indicators:** +```jsx +3 +3 +3 +3 +3 +``` + +**Dot indicators:** +```jsx + + + + + +``` + +## References + +- [Radix UI Badge Documentation](https://www.radix-ui.com/primitives/docs/components/badge) +- [API Reference](https://www.radix-ui.com/primitives/docs/components/badge#api-reference) diff --git a/docs/components/button.md b/docs/components/button.md new file mode 100644 index 0000000..8ce2744 --- /dev/null +++ b/docs/components/button.md @@ -0,0 +1,144 @@ +# Button Component Documentation + +## Overview + +The Button component is a fundamental UI element used to trigger actions or events. It supports multiple visual styles, sizes, and states for different use cases like form submission, dialog opening, action cancellation, and delete operations. + +## Props + +| Prop | Type | Default | Description | +|------|------|---------|-------------| +| `variant` | `'primary' \| 'secondary' \| 'destructive' \| 'ghost' \| 'link'` | `'primary'` | Visual appearance style | +| `size` | `'sm' \| 'base' \| 'lg'` | `'base'` | Button dimensions | +| `icon` | `boolean` | `false` | Optimizes spacing for icon-only buttons | +| `asChild` | `boolean` | `false` | Uses Slot to render as child component | +| ...button props | `ComponentProps<'button'>` | — | All standard HTML button attributes supported | + +## Variants + +### Primary +The default style for main actions: +```jsx + + + +``` + +### Secondary +Alternative action style: +```jsx + + +``` + +### Destructive +For dangerous operations like deletion: +```jsx + + +``` + +### Ghost +Subtle action style: +```jsx + + +``` + +## Sizes + +### Small +```jsx + + +``` + +### Default +```jsx + + +``` + +### Large +```jsx + + +``` + +## Icon Buttons + +Use the `icon` prop to properly space icon-only buttons across different sizes and variants: + +```jsx + + + + + +``` + +## States + +### Disabled +```jsx + + +``` + +## Type Definition + +```typescript +interface ButtonProps extends ComponentProps<"button">, VariantProps { + asChild?: boolean; + variant?: "primary" | "secondary" | "destructive" | "ghost" | "link"; + size?: "sm" | "md" | "lg"; + icon?: boolean; +} +``` + +## Usage Example + +```jsx +import { Button } from '@vuer-ai/vuer-uikit'; + +function MyComponent() { + return ( +
+ + + + + + +
+ ); +} +``` diff --git a/docs/components/card.md b/docs/components/card.md new file mode 100644 index 0000000..b540395 --- /dev/null +++ b/docs/components/card.md @@ -0,0 +1,208 @@ +- Home +- Components +- Card + +# Card + +Displays a card with header, content, and footer. + +## Props + +This component group provides styled containers. All parts accept standard div props. + +- Card: root container with size variants (sm, md, lg, xl) for padding +- CardHeader: header row with optional actions, supports size variants for gap spacing +- CardTitle: title text +- CardDescription: subdued description text +- CardAction: right-aligned action area in header +- CardContent: main content area +- CardFooter: footer area (flex container) + +## Types + +``` +// Card component with size variants +interface CardProps extends ComponentProps<"div"> { + size?: "sm" | "md" | "lg" | "xl"; +} + +// CardHeader also supports size variants for gap spacing +interface CardHeaderProps extends ComponentProps<"div"> { + size?: "sm" | "md" | "lg" | "xl"; +} + +// All other Card components extend ComponentProps<"div"> +interface CardTitleProps extends ComponentProps<"div"> {} +interface CardDescriptionProps extends ComponentProps<"div"> {} +interface CardActionProps extends ComponentProps<"div"> {} +interface CardContentProps extends ComponentProps<"div"> {} +interface CardFooterProps extends ComponentProps<"div"> {} +``` + +``` + + + Card Title + + + + + +
+
CardContent...
+
CardContent...
+
CardContent...
+
CardContent...
+
CardContent...
+
+
+ + + +
+``` + +## Sizes + +The Card component supports different padding sizes, and CardHeader adjusts gap spacing accordingly: + +``` +// Small card with reduced padding and gap spacing + + + Small Card + + + + + + Compact content with smaller padding and gap. + + + +// Large card with increased padding and gap spacing (default) + + + Large Card + + + + + + More spacious content with larger padding and gap. + + +``` + +## Login Form Example + +``` +import { Button } from "@vuer-ai/vuer-uikit" +import { + Card, + CardAction, + CardContent, + CardDescription, + CardFooter, + CardHeader, + CardTitle, +} from "@vuer-ai/vuer-uikit" +import { Input, Label } from "@vuer-ai/vuer-uikit" + + + + Login to your account + + + + + + + Enter your email below to login to your account + +
+
+
+ + +
+
+ + +
+
+
+
+ + + + +
+``` + +## Examples with Icons and Buttons + +``` +import { Settings, User, Bell, Plus, ChevronRight } from 'lucide-react'; + + + +
+ + User Profile +
+ + + +
+ + + Manage your account settings and preferences + + + + + +
+ + + +
+ + Notifications +
+
+ + 3 new updates available + + + + +
+``` + diff --git a/docs/components/checkbox.md b/docs/components/checkbox.md new file mode 100644 index 0000000..abe0536 --- /dev/null +++ b/docs/components/checkbox.md @@ -0,0 +1,62 @@ +- Home +- Components +- Checkbox + +# Checkbox + +A control that allows the user to toggle between checked and not checked. + +## Props + + +Prop Type Default Description +checkall boolean false Renders a square fill style for "select all" semantics +...Radix props ComponentProps - All Radix checkbox props + +## Types + +``` +interface CheckboxProps extends ComponentProps { + checkall?: boolean; + className?: string; +} +``` + +## Usage + +``` +
+
+ + +
+
+ + +
+
+ + +
+
+ + +
+
+ + +
+
+ + +
+
+``` + +### Examples + +``` + + +``` + diff --git a/docs/components/collapsible.md b/docs/components/collapsible.md new file mode 100644 index 0000000..47e8dff --- /dev/null +++ b/docs/components/collapsible.md @@ -0,0 +1,58 @@ +- Home +- Components +- Collapsible + +# Collapsible + +An interactive component which expands/collapses a panel. + +## Props + +All parts mirror Radix Collapsible props: + +- Collapsible: root container +- CollapsibleTrigger: toggles state (supports asChild) +- CollapsibleContent: animated content area + +### Example + +``` + + + + + Hidden content + +``` + +## Usage + +#### @peduarte starred 3 repositories + +``` + +
+

+ @peduarte starred 3 repositories +

+ + + +
+
+ @radix-ui/primitives +
+ +
+ @radix-ui/colors +
+
+ @stitches/react +
+
+
+``` + diff --git a/docs/components/cursor-display.md b/docs/components/cursor-display.md new file mode 100644 index 0000000..181d003 --- /dev/null +++ b/docs/components/cursor-display.md @@ -0,0 +1,59 @@ +- Home +- Components +- Cursor Display + +# Cursor Display + +Built-in components with Cursor highlighting + +## CursorButton + +``` +
+
+ CursorButton + CursorButton + CursorButton + CursorButton +
+
+ + + + +
+
+``` + +## CursorInputRoot + +``` + + + +``` + +## CursorSelectTrigger + +``` + + + + + + + + + +``` + +## CursorTextarea + +``` + + + + + +``` + diff --git a/docs/components/drag-selectable.md b/docs/components/drag-selectable.md new file mode 100644 index 0000000..2c71d1b --- /dev/null +++ b/docs/components/drag-selectable.md @@ -0,0 +1,82 @@ +- Home +- Components +- Drag Selectable + +# Drag Selectable + +A React component system that enables drag selection over a vertical list of items with toggle-based multi-select behavior. + +## Live Example + +Try the drag selection below: + +- Normal drag: Toggle selection +- Ctrl/Cmd + drag: Replace selection +- Escape: Clear all selections + +``` +import React from 'react'; +import { Card, Badge, useDragSelect } from '@vuer-ai/vuer-uikit'; + +const TODOS = [ + { key: "1", title: "Learn React hooks" }, + { key: "2", title: "Build a todo app" }, + { key: "3", title: "Implement drag selection" }, + // ... more items +]; + +export default function DragSelectExample() { + const { selectedItems, getItemProps, clearSelection } = useDragSelect(); + + return ( +
+ + + {TODOS.map(todo => ( + + ))} +
+ ); +} +``` + +## Simple API + +The useDragSelect() hook provides everything you need for drag selection: + +Returns: + +- selectedItems: Set - Currently selected item IDs +- getItemProps(id: string) - Props to spread on selectable items +- clearSelection() - Function to clear all selections +- isSelected(id: string) - Check if item is selected + +Usage: Just import the hook, call it, and spread getItemProps(id) on your items. The hook handles all the complex state management, event handling, and keyboard shortcuts automatically. + +## Features + +- Automatic Event Handling - Mouse and keyboard events handled internally +- Modifier Key Support - Ctrl/Cmd for replace mode, default toggle mode +- Global Events - Mouse up and Escape key work anywhere on page +- TypeScript Support - Fully typed hook and props +- Zero Dependencies - Pure React implementation + +## Selection Modes + +- Toggle (default): Items flip their selection state during drag +- Replace (Ctrl/Cmd + drag): Clear existing selection, start new selection range + +## Accessibility + +- Semantic HTML structure +- Keyboard navigation support +- Screen reader friendly markup +- Clear visual feedback for selection states + diff --git a/docs/components/drawer.md b/docs/components/drawer.md new file mode 100644 index 0000000..9bb76df --- /dev/null +++ b/docs/components/drawer.md @@ -0,0 +1,81 @@ +- Home +- Components +- Drawer + +# Drawer + +A drawer component for React. + +## Props + +### Drawer + + +Prop Type Default Description +...Vaul props ComponentProps - All Vaul drawer root props + +### Drawer Root + + +Prop Type Default Description +direction 'top' | 'right' | 'bottom' | 'left' 'bottom' Which edge to slide from +...Vaul props ComponentProps - All Vaul root props + +### DrawerContent + + +Prop Type Default Description +...Vaul props ComponentProps - All Vaul content props + +Other parts (DrawerTrigger, DrawerPortal, DrawerOverlay, DrawerHeader, DrawerFooter, DrawerTitle, DrawerDescription, DrawerClose) are styled wrappers around Vaul components. + +## Usage + +``` + + + + + { + e.preventDefault(); + }}> + + Edit profile + + Make changes to your profile here. Click save when you're done. + + +
+
+ + +
+
+ + +
+
+ + + + + + +
+
+``` + +### Example + +``` + + + + + Title + Description + + + +``` + diff --git a/docs/components/dropdown.md b/docs/components/dropdown.md new file mode 100644 index 0000000..22ca0a5 --- /dev/null +++ b/docs/components/dropdown.md @@ -0,0 +1,147 @@ +- Home +- Components +- Dropdown + +# Dropdown Menu + +Displays a menu to the user — such as a set of actions or functions — triggered by a button. + +## Props + +All primitives mirror Radix Dropdown Menu props. + +- DropdownMenu: root provider +- DropdownMenuTrigger: trigger element (supports asChild) +- DropdownMenuContent: menu content, accepts align, sideOffset +- DropdownMenuGroup, DropdownMenuLabel, DropdownMenuSeparator +- DropdownMenuItem: accepts inset?: boolean, variant?: 'default' | 'destructive' +- DropdownMenuCheckboxItem: controlled/unchecked states via checked +- DropdownMenuRadioGroup and DropdownMenuRadioItem +- DropdownMenuSub, DropdownMenuSubTrigger, DropdownMenuSubContent +- DropdownMenuShortcut: right-aligned shortcut text + +## Usage + +``` + + + + + + My Account + + + Profile + ⇧⌘P + + + Billing + ⌘B + + + Settings + ⌘S + + + Keyboard shortcuts + ⌘K + + + + + Team + + Invite users + + + Email + Message + + More... + + + + + New Team + ⌘+T + + + + GitHub + Support + API + + + Log out + ⇧⌘Q + + + +``` + +## Checkboxes + +``` + + + + + + Appearance + + + Status Bar + + + Activity Bar + + + Panel + + + +``` + +## Radio Group + +``` + + + + + + Panel Position + + + Top + Bottom + Right + + + +``` + +### Example + +``` + + + + + + Actions + New File + Delete + + Show Hidden + + +``` + diff --git a/docs/components/layout.md b/docs/components/layout.md new file mode 100644 index 0000000..15be044 --- /dev/null +++ b/docs/components/layout.md @@ -0,0 +1,70 @@ +- Home +- Components +- Layout + +#FormLayout + +A layout component for organizing content with flexible orientation and alignment options. + +## Props + + +Prop Type Default Description +orientation 'horizontal' | 'vertical' 'horizontal' Layout direction +align 'start' | 'center' | 'end' 'start' Cross-axis alignment +asChild boolean false Render with Slot to style a child element +...div props ComponentProps<'div'> - All native div props + +### Examples + +``` + + + +``` + +## Usage + +Number + +``` + + + +``` + +## vertical + +Number + +``` + + + +``` + +## vertical start + +Number + +``` + + + +``` + diff --git a/docs/components/modal.md b/docs/components/modal.md new file mode 100644 index 0000000..87531c7 --- /dev/null +++ b/docs/components/modal.md @@ -0,0 +1,88 @@ +- Home +- Components +- Modal + +# Modal + +A window overlaid on either the primary window or another dialog window, rendering the content underneath inert. + +## Props + +### Modal + + +Prop Type Default Description +...Radix props ComponentProps - All Radix Dialog root props + +### ModalContent + + +Prop Type Default Description +showCloseButton boolean true Whether to render the built-in close button +...Radix props ComponentProps - All Radix content props + +Other parts (ModalTrigger, ModalOverlay, ModalPortal, ModalHeader, ModalTitle, ModalDescription, ModalFooter, ModalClose) are thin wrappers over corresponding Radix components with styling. + +### Example + +``` + + + + + + + Title + Description + + + + + + + + +``` + +## Usage + +``` + + + + + { + e.preventDefault(); + }}> + + Edit Profile + Update your personal information. Click Save to complete the changes. + +
+
+ + +
+
+ + +
+
+ + + + + + +
+
+``` + diff --git a/docs/components/navbar.md b/docs/components/navbar.md new file mode 100644 index 0000000..ccb0465 --- /dev/null +++ b/docs/components/navbar.md @@ -0,0 +1,164 @@ +- Home +- Components +- Navbar + +# Navbar + +The Navbar component provides a consistent navigation experience across your application. It includes built-in support for search, theme switching, and mobile responsiveness. + +## Props + + +Prop Type Default Description +title string - The title/logo text to display +onSearch (query: string) => void - Callback function for search +showThemeToggle boolean false Whether to show the theme toggle +currentTheme 'light' | 'dark' | 'auto' - Current theme state +onThemeChange (theme: string) => void - Callback for theme changes + +## Overview + +The Navbar is a top-level navigation component that typically contains the application logo, navigation links, search functionality, and user controls like theme switching. + +## Features + +- Responsive Design: Automatically adapts to mobile and desktop +- Theme Switching: Built-in light/dark mode toggle +- Search Integration: Optional search functionality +- Customizable: Easy to customize with props + +## Basic Usage + +``` +import { Navbar } from '@vuer-ai/vuer-uikit'; + +function App() { + return ( + + ); +} +``` + +## With Search + +``` +import { Navbar } from '@vuer-ai/vuer-uikit'; + +function App() { + const handleSearch = (query) => { + console.log('Search query:', query); + }; + + return ( + + ); +} +``` + +## With Theme Toggle + +``` +import { Navbar } from '@vuer-ai/vuer-uikit'; + +function App() { + return ( + + ); +} +``` + +## API Reference + +### Examples + +#### Basic Navbar + +``` + +``` + +#### Navbar with Search + +``` + { + // Handle search + console.log('Searching for:', query); + }} +/> +``` + +#### Navbar with Theme Toggle + +``` + { + // Handle theme change + console.log('Theme changed to:', theme); + }} +/> +``` + +## Mobile Behavior + +On mobile devices, the navbar automatically adapts: + +- Search bar collapses into a mobile-friendly interface +- Theme toggle remains accessible +- Touch targets are appropriately sized +- Responsive breakpoints ensure good UX + +## Customization + +### Styling + +You can customize the navbar appearance using CSS custom properties: + +``` +.vuer-navbar { + --navbar-bg: var(--neutral-50); + --navbar-border: var(--neutral-200); + --navbar-height: 4rem; + --navbar-padding: 1rem; +} +``` + +### Custom Content + +For more complex navigation needs, you can extend the navbar with custom content: + +``` + + + +``` + +## Accessibility + +- Proper semantic HTML structure +- Keyboard navigation support +- Screen reader announcements +- Focus management +- ARIA labels and descriptions + +## Best Practices + +- Keep the title concise and recognizable +- Provide meaningful search functionality +- Use theme toggle for better user experience +- Ensure mobile responsiveness +- Test with keyboard navigation + diff --git a/docs/components/navigation.md b/docs/components/navigation.md new file mode 100644 index 0000000..c8ebf39 --- /dev/null +++ b/docs/components/navigation.md @@ -0,0 +1,54 @@ +- Home +- Components +- Navigation + +# Navigation + +A navigation component with back/forward buttons and title display. + +## Props + + +Prop Type Default Description +title string - The title text to display +onBack () => void - Callback for back button click +onForward () => void - Callback for forward button click +canGoBack boolean true Whether the back button should be enabled +canGoForward boolean true Whether the forward button should be enabled +size "sm" | "md" | "lg" "md" Size variant for buttons and title +className string - Additional CSS class names + +## Basic Usage + +``` + +``` + +## Sizes + +``` + + + +``` + +## Disabled States + +``` + + + +``` + diff --git a/docs/components/pagination.md b/docs/components/pagination.md new file mode 100644 index 0000000..5f4fcf0 --- /dev/null +++ b/docs/components/pagination.md @@ -0,0 +1,44 @@ +- Home +- Components +- Pagination + +## Pagination + +Pagination with page navigation, next and previous links. + +## Usage + +- Previous +- 1 +- 2 +- 3 +- More pages +- Next + +``` + + + + + + + 1 + + + + 2 + + + + 3 + + + + + + + + + +``` + diff --git a/docs/components/popover.md b/docs/components/popover.md new file mode 100644 index 0000000..95e003d --- /dev/null +++ b/docs/components/popover.md @@ -0,0 +1,95 @@ +- Home +- Components +- Popover + +# Popover + +Displays rich content in a portal, triggered by a button. + +## Props + +### Popover + + +Prop Type Default Description +...Radix props ComponentProps - All Radix Popover root props + +### PopoverContent + + +Prop Type Default Description +align 'start' | 'center' | 'end' 'center' Content alignment relative to trigger +sideOffset number 4 Offset in pixels from the trigger +...Radix props ComponentProps - All Radix content props + +## Usage + +``` + + + + + { + e.preventDefault(); + }}> +
+
+

Dimensions

+

+ Set the dimensions for the layer. +

+
+
+ + + + + + + + + + + + +
+
+
+
+``` + +### Example + +``` + + + + + Content + +``` + diff --git a/docs/components/preview.md b/docs/components/preview.md new file mode 100644 index 0000000..ec0f4d9 --- /dev/null +++ b/docs/components/preview.md @@ -0,0 +1,97 @@ +- Home +- Components +- Preview + +# Preview + +The Preview component is used throughout the documentation to display components alongside their code examples. It supports flexible layouts for showcasing components in different arrangements. + +## FormLayout Options + +## Default Layout + +By default, the Preview component displays components horizontally with code below: + +``` + +``` + +### Left Layout + +Use left prop to position the component on the left side with a fixed width: + +``` + +``` + +### Right Layout + +Use right prop to position the component on the right side with a fixed width: + +``` + +``` + +### Custom Width + +You can specify custom widths for left or right layouts: + +``` + +``` + +``` + +``` + +## Props + +### Required Props + + +Prop Type Description +children ReactNode Required. The code example content to display. Typically contains a markdown code block with syntax highlighting. +component ReactNode Required. The actual component or JSX element to render in the preview panel. + +### Layout Props + + +Prop Type Default Description +left boolean | number undefined Positions the component on the left side with code on the right. If true, uses default width of 200px. If a number, uses that value as width in pixels. +right boolean | number undefined Positions the component on the right side with code on the left. If true, uses default width of 200px. If a number, uses that value as width in pixels. + +### Code Block Props + + +Prop Type Default Description +lines number undefined Fixed height in lines. If collapsed=true, shows this many lines when collapsed. If collapsed=false, uses this as max height with scroll. +collapsed boolean false Enable collapse/expand button functionality. +startCollapsed boolean false Start in collapsed state (requires collapsed=true). +maxLines number undefined When expanded, max lines before adding scroll. Only works with collapsed=true. + +### Default Values + +The Preview component uses these constants for default widths: + +- Default left width: 200px (when left={true}) +- Default right width: 200px (when right={true}) + +### Layout Behavior + +- Default layout (no left or right prop): Component displays above the code block in a horizontal stack +- Left layout (left prop): Component panel on left (fixed width), code panel on right (flexible width) +- Right layout (right prop): Code panel on left (flexible width), component panel on right (fixed width) +- Mutual exclusivity: Only use either left OR right, never both simultaneously + +## Usage Notes + +- Only use either left OR right prop, not both +- When no layout prop is provided, uses the default horizontal layout +- The Preview component handles responsive behavior and code block styling automatically +- Default widths are 200px for both left and right layouts +- Code blocks automatically include copy buttons +- Use collapsed={true} to enable collapse/expand functionality +- Use lines={n} for fixed height or collapsed display height +- Use maxLines={n} with collapsed={true} to control expanded height +- Use startCollapsed={true} to begin in collapsed state + diff --git a/docs/components/progress.md b/docs/components/progress.md new file mode 100644 index 0000000..fe139e9 --- /dev/null +++ b/docs/components/progress.md @@ -0,0 +1,65 @@ +- Home +- Components +- Progress + +# Progress + +Displays an indicator showing the completion progress of a task, typically displayed as a progress bar. + +## Props + + +Prop Type Default Description +value number 0 The progress value (0-100) +max number 100 The maximum value +className string - Additional CSS classes +...progress props ComponentProps - All Radix Progress props are supported + +## Basic Usage + +``` +
+
+ 0% + +
+
+ 50% + +
+
+ 100% + +
+
+``` + +## Animated Progress + +``` +function AnimatedProgress() { + const [progress, setProgress] = useState(0); + + useEffect(() => { + const timer = setInterval(() => { + setProgress((prev) => { + if (prev >= 100) return 0; + return prev + 10; + }); + }, 500); + + return () => clearInterval(timer); + }, []); + + return ( +
+
+ Animated Progress + {progress}% +
+ +
+ ); +} +``` + diff --git a/docs/components/radio-group.md b/docs/components/radio-group.md new file mode 100644 index 0000000..a88b4cd --- /dev/null +++ b/docs/components/radio-group.md @@ -0,0 +1,61 @@ +- Home +- Components +- Radio Group + +# RadioGroup + +A set of checkable buttons—known as radio buttons—where no more than one of the buttons can be checked at a time. + +## Props + + +Component Notes +RadioGroup Pass-through wrapper over Radix RadioGroup.Root with layout classes +RadioGroupItem Pass-through wrapper over Radix RadioGroup.Item with styles + +All Radix props are supported. + +### Example + +``` + +
+ + +
+
+``` + +## Usage + +``` + +
+ + +
+
+ + +
+
+ + +
+
+ +
+ + +
+
+ + +
+
+ + +
+
+``` + diff --git a/docs/components/select.md b/docs/components/select.md new file mode 100644 index 0000000..5198a42 --- /dev/null +++ b/docs/components/select.md @@ -0,0 +1,241 @@ +- Home +- Components +- Select + +# Select + +Displays a list of options for the user to pick from—triggered by a button. + +## Types + +``` +interface SelectTriggerProps extends ComponentProps, VariantProps { + state?: "default" | "disabled" | "error"; + size?: "sm" | "md" | "lg"; + font?: "standard" | "mono"; + align?: "left" | "center" | "right"; +} + +interface SelectItemProps extends ComponentProps { + prefix?: ReactNode; + suffix?: ReactNode; +} + +// Other select components use Radix primitives: +// SelectRoot, SelectGroup, SelectValue, SelectContent, +// SelectLabel, SelectSeparator - all extend Radix component props +``` + +## In Toolbar + +``` + + + + + + + +``` + +## Props + +### Select + + +Prop Type Default Description +font 'standard' | 'mono' 'mono' Font family applied to trigger and items +align 'left' | 'center' | 'right' 'left' Text alignment applied to trigger and items +...Radix props ComponentProps - All Radix Select root props + +### SelectTrigger + + +Prop Type Default Description +size 'sm' | 'md' | 'lg' 'md' Trigger size +state 'default' | 'error' 'default' Visual state +...Radix props ComponentProps - All Radix trigger props + +### SelectContent + + +Prop Type Default Description +position 'item-aligned' | 'popper' 'item-aligned' Positioning strategy +...Radix props ComponentProps - All Radix content props + +### SelectItem + + +Prop Type Default Description +prefix ReactNode - Element rendered before the label +suffix ReactNode - Element rendered after the label +...Radix props ComponentProps - All Radix item props + +### SelectLabel, SelectGroup, SelectSeparator, SelectScrollUpButton, SelectScrollDownButton, SelectValue + +Pass-through wrappers for corresponding Radix components. + +## Usage + +``` + +``` + +## State + +``` + +``` + +## Sides + +Left + +Top + +Bottom + +Right + +``` +

Left

+ +``` + +## Font Styles + +Standard Font + +Mono Font + +``` +{/* Standard font */} + + +{/* Monospace font (default) */} + +``` + +## Text Alignment + +Left Aligned + +Center Aligned + +Right Aligned + +``` +{/* Left aligned (default) */} + + +{/* Center aligned */} + + +{/* Right aligned */} + +``` + +## Error + +``` + +``` + diff --git a/docs/components/sheet.md b/docs/components/sheet.md new file mode 100644 index 0000000..205859c --- /dev/null +++ b/docs/components/sheet.md @@ -0,0 +1,77 @@ +- Home +- Components +- Sheet + +# Sheet + +Extends the Dialog component to display content that complements the main content of the screen. + +## Props + +### Sheet + + +Prop Type Default Description +...Radix props ComponentProps - All Radix Dialog root props + +### SheetContent + + +Prop Type Default Description +side 'top' | 'right' | 'bottom' | 'left' 'right' Which edge to slide from +...Radix props ComponentProps - All Radix content props + +Other parts (SheetTrigger, SheetClose, SheetHeader, SheetFooter, SheetTitle, SheetDescription) are styled wrappers around Radix components. + +### Example + +``` + + + + + + + Title + Optional description + + + +``` + +## Usage + +``` + + + + + { + e.preventDefault(); + }}> + + Edit profile + + Make changes to your profile here. Click save when you're done. + + +
+
+ + +
+
+ + +
+
+ + + + + + +
+
+``` + diff --git a/docs/components/sidebar.md b/docs/components/sidebar.md new file mode 100644 index 0000000..02adc88 --- /dev/null +++ b/docs/components/sidebar.md @@ -0,0 +1,156 @@ +1. Home +2. Components +3. Sidebar + +# Sidebar + +A composable, themeable and customizable sidebar component. + +## Usage + +Ge's Team - Documents +- Team +- Communication +- SidebarMenuAction +- SidebarMenuBadge24 + +Toggle Sidebar ```jsx +import { ChevronDown, ChevronRight, Folder, FileText, Users, Mail, Bell } from "lucide-react" +import { useState } from "react" + +const collapsibleItems = [ + { + title: "Documents", + icon: Folder, + items: [ + { title: "Reports", url: "#", icon: FileText }, + { title: "Invoices", url: "#", icon: FileText }, + { title: "Contracts", url: "#", icon: FileText }, + ], + }, + { + title: "Team", + icon: Users, + items: [ + { title: "Members", url: "#", icon: Users }, + { title: "Roles", url: "#", icon: Users }, + { title: "Permissions", url: "#", icon: Users }, + ], + }, + { + title: "Communication", + icon: Mail, + items: [ + { title: "Messages", url: "#", icon: Mail }, + { title: "Notifications", url: "#", icon: Bell }, + { title: "Announcements", url: "#", icon: Bell }, + ], + }, +] + +function CollapsibleMenuItem({ item }) { + const [isOpen, setIsOpen] = useState(false) + + return ( + <> + + setIsOpen(!isOpen)} className="pl-lg"> + + {item.title} + {isOpen ? : } + + {isOpen && ( + + {item.items.map((subItem) => ( + + + + + {subItem.title} + + + + ))} + + )} + + + + ) +} + + + + + + +
+ + + GT + +
+ Ge's Team + +
+
+
+ + + Menu item1 + + + Menu item2 + + + Menu item3 + + +
+
+ + + + + + {collapsibleItems.map((item) => ( + + ))} + + +
SidebarMenuAction
+
+ + + + + + + + + Edit Project + + + Delete Project + + + +
+ + +
SidebarMenuBadge
+
+ 24 +
+
+
+
+
+ +
+ +
+``` \ No newline at end of file diff --git a/docs/components/simple-tree-view.md b/docs/components/simple-tree-view.md new file mode 100644 index 0000000..8288137 --- /dev/null +++ b/docs/components/simple-tree-view.md @@ -0,0 +1,98 @@ +1. Home +2. Components +3. Simple Tree View + +# SimpleTreeView + +## Types + +```typescript +interface TreeDataItem { + id: string; + name: string; + icon?: IconComponent; + selectedIcon?: IconComponent; + openIcon?: IconComponent; + children?: TreeDataItem[]; + actions?: ReactNode; + onClick?: () => void; + draggable?: boolean; + droppable?: boolean; + disabled?: boolean; +} + +type IconComponent = React.ComponentType<{ className?: string }>; +``` + +# Simple Tree View + +## Props + +### SimpleTreeView + +| Prop | Type | Description | +| --- | --- | --- | +| data | `TreeDataItem[] | TreeDataItem` | +| initialSelectedItemId | string | Preselect an item and auto-expand ancestors | +| onSelectChange | (item?: TreeDataItem) => void | Callback when selection changes | +| expandAll | boolean | Expand all nodes initially | +| defaultNodeIcon | IconComponent | Default icon for nodes | +| defaultLeafIcon | IconComponent | Default icon for leaves | +| onDocumentDrag | (source: TreeDataItem, target: TreeDataItem) => void | Drag and drop callback | + +### TreeDataItem + +```ts +type TreeDataItem = { + id: string; + name: string; + icon?: ComponentType>; + selectedIcon?: ComponentType>; + openIcon?: ComponentType>; + children?: TreeDataItem[]; + actions?: React.ReactNode; + onClick?: () => void; + draggable?: boolean; + droppable?: boolean; + disabled?: boolean; +} +``` + +- Item 1 +- Item 2 +- Item 3 + +```jsx +const data = [ + { id: '1', name: 'Item 1', icon: ArrowRight, + children: [ + { id: '2', name: 'Item 1.1', icon: AlarmClock, + children: [ + { id: '3', name: 'Item 1.1.1', icon: Ambulance }, + { id: '4', name: 'Item 1.1.2', icon: Angry }, + ], + }, + { id: '5', name: 'Item 1.2 (disabled)', icon: Album, disabled: true }, + ], + }, { + id: '6', name: 'Item 2', + children: [ + { id: '7', name: 'Item 2.1', icon: AlignCenterHorizontal }, + { id: '8', name: 'Item 2.2', icon: Blend, + children: [ + { id: '9', name: 'Item 2.2.1', icon: Bird }, + { id: '10', name: 'Item 2.2.2', icon: Biohazard, + children: [ + { id: '11', name: 'Item 2.2.2.1', icon: Cannabis }, + { id: '12', name: 'Item 2.2.2.2 Item 2.2.2.2 Item 2.2.2.2 Item 2.2.2.2 Item 2.2.2.2', icon: Cannabis } + ] + }, + ], + }, + ], + }, + { id: '13', name: 'Item 3' } +]; + + +``` \ No newline at end of file diff --git a/docs/components/slider.md b/docs/components/slider.md new file mode 100644 index 0000000..ee0b72f --- /dev/null +++ b/docs/components/slider.md @@ -0,0 +1,76 @@ +1. Home +2. Components +3. Slider + +# Slider + +An input where the user selects a value from within a given range. + +[Docs](https://www.radix-ui.com/primitives/docs/components/slider)[API Reference](https://www.radix-ui.com/primitives/docs/components/slider#api-reference)## Props + +| Prop | Type | Default | Description | +| --- | --- | --- | --- | +| showStep | boolean | false | Visualize step marks along the track | +| min | number | 0 | Minimum value | +| max | number | 100 | Maximum value | +| step | number | 1 | Step size | +| value | number[] | - | Controlled values for one or more thumbs | +| defaultValue | number[] | - | Uncontrolled initial values | +| onValueChange | (value: number[]) => void | - | Callback when value changes | +| ...Radix props | ComponentProps | - | All Radix slider props | + +## Usage + +```jsx + +``` + +### Create a range + +```jsx + +``` + +### Prevent thumb overlap + +```jsx + +``` + +### Define step size + +```jsx + +``` + +### Define step size and show + +```jsx + +``` + +```jsx + +``` + +### Examples + +```jsx +// Single value + + +// Range + +``` + +### Disabled + +```jsx + +``` + +### Disabled with step + +```jsx + +``` \ No newline at end of file diff --git a/docs/components/spinner.md b/docs/components/spinner.md new file mode 100644 index 0000000..f72b9c1 --- /dev/null +++ b/docs/components/spinner.md @@ -0,0 +1,46 @@ +1. Home +2. Components +3. Spinner + +# Spinner + +The Spinner component provides a visual loading indicator with a smooth ring animation. +It's built using SVG animations for optimal performance and customization. + +## Props + +| Prop | Type | Default | Description | +| --- | --- | --- | --- | +| size | number | 24 | Size of the spinner in pixels | +| className | string | - | Additional CSS classes | +| style | CSSProperties | - | Inline styles | +| ...svg props | SVGProps | - | All native SVG props are supported | + +## Overview + +Spinners are used to indicate loading states or ongoing processes. They provide visual feedback to users that the application is working on their request. + +## Basic Usage + +Loading... Loading... Loading... ```jsx +// Default spinner + + +// Medium spinner + + +// Large spinner + +``` + +## Custom Styling + +Loading... Loading... Loading... Loading... ```jsx +// Custom colors using className + + + + +// Custom color using style + +``` \ No newline at end of file diff --git a/docs/components/switch.md b/docs/components/switch.md new file mode 100644 index 0000000..04713b2 --- /dev/null +++ b/docs/components/switch.md @@ -0,0 +1,42 @@ +1. Home +2. Components +3. Switch + +# Switch + +A control that allows the user to toggle between checked and not checked. + +[Docs](https://www.radix-ui.com/primitives/docs/components/switch)[API Reference](https://www.radix-ui.com/primitives/docs/components/switch#api-reference)[shadcn/ui](https://ui.shadcn.com/docs/components/switch)## Props + +| Prop | Type | Default | Description | +| --- | --- | --- | --- | +| ...Radix props | ComponentProps | - | All Radix switch root props | + +### Examples + +```jsx + +``` + +## Usage + +Switch Switch checked Switch disabled Switch disabled checked ```jsx +
+
+ + +
+
+ + +
+
+ + +
+
+ + +
+
+``` \ No newline at end of file diff --git a/docs/components/sync-scroll.md b/docs/components/sync-scroll.md new file mode 100644 index 0000000..fc9abab --- /dev/null +++ b/docs/components/sync-scroll.md @@ -0,0 +1,237 @@ +1. Home +2. Components +3. Sync Scroll + +# Synchronized Scrolling Components + +Components for creating synchronized scrolling experiences with master-slave relationships and drag-to-scroll functionality. + +## Basic Usage with Components + +Master Scroll Item 1 Item 2 Item 3 Item 4 Item 5 Item 6 Item 7 Item 8 Item 9 Item 10 Item 11 Item 12 Item 13 Item 14 Item 15 Item 16 Item 17 Item 18 Item 19 Item 20 Item 21 Item 22 Item 23 Item 24 Item 25 Item 26 Item 27 Item 28 Item 29 Item 30 Item 31 Item 32 Item 33 Item 34 Item 35 Item 36 Item 37 Item 38 Item 39 Item 40 Item 41 Item 42 Item 43 Item 44 Item 45 Item 46 Item 47 Item 48 Item 49 Item 50 Slave Scroll Item 1 Item 2 Item 3 Item 4 Item 5 Item 6 Item 7 Item 8 Item 9 Item 10 Item 11 Item 12 Item 13 Item 14 Item 15 Item 16 Item 17 Item 18 Item 19 Item 20 Item 21 Item 22 Item 23 Item 24 Item 25 Item 26 Item 27 Item 28 Item 29 Item 30 Item 31 Item 32 Item 33 Item 34 Item 35 Item 36 Item 37 Item 38 Item 39 Item 40 Item 41 Item 42 Item 43 Item 44 Item 45 Item 46 Item 47 Item 48 Item 49 Item 50 ```jsx +import {SyncScrollProvider, SyncScroll, SyncScrollSlave} from "@vuer-ai/vuer-uikit"; + +function App() { +return ( + + +{/* Master scrollable content */} + + + +{/* Slave synchronized scroll area */} + + +); +} +``` + +## With Drag Control + +The drag components now include built-in drag-to-scroll functionality. Click and drag to scroll! + +SyncScroll Item 1 Item 2 Item 3 Item 4 Item 5 Item 6 Item 7 Item 8 Item 9 Item 10 Item 11 Item 12 Item 13 Item 14 Item 15 Item 16 Item 17 Item 18 Item 19 Item 20 Item 21 Item 22 Item 23 Item 24 Item 25 Item 26 Item 27 Item 28 Item 29 Item 30 Item 31 Item 32 Item 33 Item 34 Item 35 Item 36 Item 37 Item 38 Item 39 Item 40 Item 41 Item 42 Item 43 Item 44 Item 45 Item 46 Item 47 Item 48 Item 49 Item 50 SyncDrag 🖱️ Click and drag vertically to scroll all panels Item 1 Item 2 Item 3 Item 4 Item 5 Item 6 Item 7 Item 8 Item 9 Item 10 Item 11 Item 12 Item 13 Item 14 Item 15 Item 16 Item 17 Item 18 Item 19 Item 20 Item 21 Item 22 Item 23 Item 24 Item 25 Item 26 Item 27 Item 28 Item 29 Item 30 Item 31 Item 32 Item 33 Item 34 Item 35 Item 36 Item 37 Item 38 Item 39 Item 40 Item 41 Item 42 Item 43 Item 44 Item 45 Item 46 Item 47 Item 48 Item 49 Item 50 SyncScrollSlave Item 1 Item 2 Item 3 Item 4 Item 5 Item 6 Item 7 Item 8 Item 9 Item 10 Item 11 Item 12 Item 13 Item 14 Item 15 Item 16 Item 17 Item 18 Item 19 Item 20 Item 21 Item 22 Item 23 Item 24 Item 25 Item 26 Item 27 Item 28 Item 29 Item 30 Item 31 Item 32 Item 33 Item 34 Item 35 Item 36 Item 37 Item 38 Item 39 Item 40 Item 41 Item 42 Item 43 Item 44 Item 45 Item 46 Item 47 Item 48 Item 49 Item 50 ```jsx +import {SyncScrollProvider, SyncScroll, SyncDrag, SyncScrollSlave} from "@vuer-ai/vuer-uikit"; + +function App() { +return ( + + +{/* Master scrollable content */} + + + +{/* Draggable content with vertical drag-to-scroll */} + + + +{/* Slave synchronized area */} + + +); +} +``` + +## Horizontal Drag Variants + +Horizontal drag components allow left/right scrolling via drag gestures: + +### Horizontal Draggable Panels - Both Can Be Dragged + +Drag either panel to control both - Master (left) overrides Slave (right) + +MASTER DRAG (SyncDragX) 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 SLAVE DRAG (SyncDragSlaveX) 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 ```jsx +import {SyncScrollProvider, SyncDragX, SyncDragSlaveX} from "@vuer-ai/vuer-uikit"; + +function App() { +return ( + +
+{/* Master drag - controls all */} + +
+ {/* Horizontal content */} +
+
+ +{/* Slave drag - follows master but can be dragged */} + +
+ {/* Horizontal content */} +
+
+
+
+); +} +``` + +## Omnidirectional Drag Variants + +Omnidirectional drag components allow scrolling in any direction via drag gestures: + +### Omnidirectional Draggable Panels - Both Can Be Dragged + +Drag either panel in any direction - Master (left) overrides Slave (right) + +MASTER DRAG (SyncDrag) 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 SLAVE DRAG (SyncDragSlave) 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 ```jsx +import {SyncScrollProvider, SyncDrag, SyncDragSlave} from "@vuer-ai/vuer-uikit"; + +function App() { +return ( + +
+{/* Master drag - controls all */} + +
+ {/* Content that scrolls in both directions */} +
+
+ +{/* Slave drag - follows master but can be dragged */} + +
+ {/* Content that scrolls in both directions */} +
+
+
+
+); +} +``` + +## Using Hooks Directly + +For more control, you can use the hooks directly: + +useSyncScroll Hook Item 1 Item 2 Item 3 Item 4 Item 5 Item 6 Item 7 Item 8 Item 9 Item 10 Item 11 Item 12 Item 13 Item 14 Item 15 Item 16 Item 17 Item 18 Item 19 Item 20 Item 21 Item 22 Item 23 Item 24 Item 25 Item 26 Item 27 Item 28 Item 29 Item 30 Item 31 Item 32 Item 33 Item 34 Item 35 Item 36 Item 37 Item 38 Item 39 Item 40 Item 41 Item 42 Item 43 Item 44 Item 45 Item 46 Item 47 Item 48 Item 49 Item 50 useScrollSlave Hook Item 1 Item 2 Item 3 Item 4 Item 5 Item 6 Item 7 Item 8 Item 9 Item 10 Item 11 Item 12 Item 13 Item 14 Item 15 Item 16 Item 17 Item 18 Item 19 Item 20 Item 21 Item 22 Item 23 Item 24 Item 25 Item 26 Item 27 Item 28 Item 29 Item 30 Item 31 Item 32 Item 33 Item 34 Item 35 Item 36 Item 37 Item 38 Item 39 Item 40 Item 41 Item 42 Item 43 Item 44 Item 45 Item 46 Item 47 Item 48 Item 49 Item 50 useSyncDrag Hook Item 1 Item 2 Item 3 Item 4 Item 5 Item 6 Item 7 Item 8 Item 9 Item 10 Item 11 Item 12 Item 13 Item 14 Item 15 Item 16 Item 17 Item 18 Item 19 Item 20 Item 21 Item 22 Item 23 Item 24 Item 25 Item 26 Item 27 Item 28 Item 29 Item 30 Item 31 Item 32 Item 33 Item 34 Item 35 Item 36 Item 37 Item 38 Item 39 Item 40 Item 41 Item 42 Item 43 Item 44 Item 45 Item 46 Item 47 Item 48 Item 49 Item 50 ```jsx +import {SyncScrollProvider, useSyncScroll, useScrollSlave, useSyncDrag} from "@vuer-ai/vuer-uikit"; + +// Master panel - controls all other panels +function MasterPanel() { +const ref = useSyncScroll(); + +return ( +
+{/* Your scrollable content */} +
+); +} + +// Slave panel - controlled by master, syncs with other slaves +function SlavePanel() { +const ref = useScrollSlave(); + +return ( +
+ {/* Your scrollable content */} +
+); +} + +// Drag panel - acts like master when dragged +function DragPanel() { +const ref = useSyncDrag(); + +return ( +
+ {/* Your draggable content */} +
+); +} + +function App() { +return ( + + + + + +); +} +``` + +## API Reference + +### Components + +#### + +Wraps components that need synchronized scrolling. + +#### + +A scrollable container that synchronizes with other scroll components. Acts as a master that controls all other synchronized elements. + +Props: Extends HTMLAttributes + +#### + +A scrollable container that is controlled by masters and syncs with other slaves. + +Props: Extends HTMLAttributes + +#### + +A draggable container that supports both horizontal and vertical drag-to-scroll. Click and drag in any direction to scroll both horizontally and vertically. Controls synchronized scrolling. + +Props: Extends HTMLAttributes + +#### + +A draggable container that only supports horizontal drag-to-scroll. Click and drag left/right to scroll horizontally only (vertical dragging is disabled). Controls synchronized scrolling. + +Props: Extends HTMLAttributes + +### Hooks + +#### useSyncScroll() + +Returns a ref for a master scroll element that controls all other elements. + +#### useScrollSlave() + +Returns a ref for a slave scroll element that is controlled by masters and syncs with other slaves. + +#### useSyncDrag() + +Returns a ref for drag-controlled scrolling that acts like a master in synchronized scrolling. + +### Behavior Notes + +- Master elements (SyncScroll, useSyncScroll): Control all other synchronized elements +- Slave elements (SyncScrollSlave, useScrollSlave): Are controlled by masters and sync with other slaves +- Drag elements (SyncDrag, SyncDragX, Drag, useSyncDrag): Act like masters with built-in drag-to-scroll functionality +- SyncDrag: Vertical drag-to-scroll +- SyncDragX: Horizontal drag-to-scroll +- Drag: Omnidirectional drag-to-scroll + +📍 SyncScroll: Master scroll control - scrolling affects all synchronized elements + +📍 SyncScrollSlave: Controlled by masters, syncs with other slaves + +📍 SyncDrag: Vertical drag-to-scroll that controls all synchronized elements + +📍 SyncDragX: Horizontal drag-to-scroll that controls all synchronized elements + +📍 Drag: Omnidirectional drag-to-scroll that controls all synchronized elements \ No newline at end of file diff --git a/docs/components/table.md b/docs/components/table.md new file mode 100644 index 0000000..19b5d11 --- /dev/null +++ b/docs/components/table.md @@ -0,0 +1,82 @@ +1. Home +2. Components +3. Drag Selectable + +# Drag Selectable + +A React component system that enables drag selection over a vertical list of items with toggle-based multi-select behavior. + +## Live Example + +Try the drag selection below: + +- Normal drag: Toggle selection +- Ctrl/Cmd + drag: Replace selection +- Escape: Clear all selections + +0 item s selected Clear All Learn React hooks Build a todo app Implement drag selection Style with Tailwind CSS Add dark mode support Write unit tests Deploy to production Add keyboard shortcuts Improve accessibility Add animations ```tsx +import React from 'react'; +import { Card, Badge, useDragSelect } from '@vuer-ai/vuer-uikit'; + +const TODOS = [ + { key: "1", title: "Learn React hooks" }, + { key: "2", title: "Build a todo app" }, + { key: "3", title: "Implement drag selection" }, + // ... more items +]; + +export default function DragSelectExample() { + const { selectedItems, getItemProps, clearSelection } = useDragSelect(); + + return ( +
+ + + {TODOS.map(todo => ( + + ))} +
+ ); +} +``` + +## Simple API + +The useDragSelect() hook provides everything you need for drag selection: + +Returns: + +- selectedItems: Set - Currently selected item IDs +- getItemProps(id: string) - Props to spread on selectable items +- clearSelection() - Function to clear all selections +- isSelected(id: string) - Check if item is selected + +Usage: +Just import the hook, call it, and spread getItemProps(id) on your items. The hook handles all the complex state management, event handling, and keyboard shortcuts automatically. + +## Features + +- Automatic Event Handling - Mouse and keyboard events handled internally +- Modifier Key Support - Ctrl/Cmd for replace mode, default toggle mode +- Global Events - Mouse up and Escape key work anywhere on page +- TypeScript Support - Fully typed hook and props +- Zero Dependencies - Pure React implementation + +## Selection Modes + +- Toggle (default): Items flip their selection state during drag +- Replace (Ctrl/Cmd + drag): Clear existing selection, start new selection range + +## Accessibility + +- Semantic HTML structure +- Keyboard navigation support +- Screen reader friendly markup +- Clear visual feedback for selection states \ No newline at end of file diff --git a/docs/components/tabs.md b/docs/components/tabs.md new file mode 100644 index 0000000..19b5d11 --- /dev/null +++ b/docs/components/tabs.md @@ -0,0 +1,82 @@ +1. Home +2. Components +3. Drag Selectable + +# Drag Selectable + +A React component system that enables drag selection over a vertical list of items with toggle-based multi-select behavior. + +## Live Example + +Try the drag selection below: + +- Normal drag: Toggle selection +- Ctrl/Cmd + drag: Replace selection +- Escape: Clear all selections + +0 item s selected Clear All Learn React hooks Build a todo app Implement drag selection Style with Tailwind CSS Add dark mode support Write unit tests Deploy to production Add keyboard shortcuts Improve accessibility Add animations ```tsx +import React from 'react'; +import { Card, Badge, useDragSelect } from '@vuer-ai/vuer-uikit'; + +const TODOS = [ + { key: "1", title: "Learn React hooks" }, + { key: "2", title: "Build a todo app" }, + { key: "3", title: "Implement drag selection" }, + // ... more items +]; + +export default function DragSelectExample() { + const { selectedItems, getItemProps, clearSelection } = useDragSelect(); + + return ( +
+ + + {TODOS.map(todo => ( + + ))} +
+ ); +} +``` + +## Simple API + +The useDragSelect() hook provides everything you need for drag selection: + +Returns: + +- selectedItems: Set - Currently selected item IDs +- getItemProps(id: string) - Props to spread on selectable items +- clearSelection() - Function to clear all selections +- isSelected(id: string) - Check if item is selected + +Usage: +Just import the hook, call it, and spread getItemProps(id) on your items. The hook handles all the complex state management, event handling, and keyboard shortcuts automatically. + +## Features + +- Automatic Event Handling - Mouse and keyboard events handled internally +- Modifier Key Support - Ctrl/Cmd for replace mode, default toggle mode +- Global Events - Mouse up and Escape key work anywhere on page +- TypeScript Support - Fully typed hook and props +- Zero Dependencies - Pure React implementation + +## Selection Modes + +- Toggle (default): Items flip their selection state during drag +- Replace (Ctrl/Cmd + drag): Clear existing selection, start new selection range + +## Accessibility + +- Semantic HTML structure +- Keyboard navigation support +- Screen reader friendly markup +- Clear visual feedback for selection states \ No newline at end of file diff --git a/docs/components/textarea.md b/docs/components/textarea.md new file mode 100644 index 0000000..19b5d11 --- /dev/null +++ b/docs/components/textarea.md @@ -0,0 +1,82 @@ +1. Home +2. Components +3. Drag Selectable + +# Drag Selectable + +A React component system that enables drag selection over a vertical list of items with toggle-based multi-select behavior. + +## Live Example + +Try the drag selection below: + +- Normal drag: Toggle selection +- Ctrl/Cmd + drag: Replace selection +- Escape: Clear all selections + +0 item s selected Clear All Learn React hooks Build a todo app Implement drag selection Style with Tailwind CSS Add dark mode support Write unit tests Deploy to production Add keyboard shortcuts Improve accessibility Add animations ```tsx +import React from 'react'; +import { Card, Badge, useDragSelect } from '@vuer-ai/vuer-uikit'; + +const TODOS = [ + { key: "1", title: "Learn React hooks" }, + { key: "2", title: "Build a todo app" }, + { key: "3", title: "Implement drag selection" }, + // ... more items +]; + +export default function DragSelectExample() { + const { selectedItems, getItemProps, clearSelection } = useDragSelect(); + + return ( +
+ + + {TODOS.map(todo => ( + + ))} +
+ ); +} +``` + +## Simple API + +The useDragSelect() hook provides everything you need for drag selection: + +Returns: + +- selectedItems: Set - Currently selected item IDs +- getItemProps(id: string) - Props to spread on selectable items +- clearSelection() - Function to clear all selections +- isSelected(id: string) - Check if item is selected + +Usage: +Just import the hook, call it, and spread getItemProps(id) on your items. The hook handles all the complex state management, event handling, and keyboard shortcuts automatically. + +## Features + +- Automatic Event Handling - Mouse and keyboard events handled internally +- Modifier Key Support - Ctrl/Cmd for replace mode, default toggle mode +- Global Events - Mouse up and Escape key work anywhere on page +- TypeScript Support - Fully typed hook and props +- Zero Dependencies - Pure React implementation + +## Selection Modes + +- Toggle (default): Items flip their selection state during drag +- Replace (Ctrl/Cmd + drag): Clear existing selection, start new selection range + +## Accessibility + +- Semantic HTML structure +- Keyboard navigation support +- Screen reader friendly markup +- Clear visual feedback for selection states \ No newline at end of file diff --git a/docs/components/toast.md b/docs/components/toast.md new file mode 100644 index 0000000..19b5d11 --- /dev/null +++ b/docs/components/toast.md @@ -0,0 +1,82 @@ +1. Home +2. Components +3. Drag Selectable + +# Drag Selectable + +A React component system that enables drag selection over a vertical list of items with toggle-based multi-select behavior. + +## Live Example + +Try the drag selection below: + +- Normal drag: Toggle selection +- Ctrl/Cmd + drag: Replace selection +- Escape: Clear all selections + +0 item s selected Clear All Learn React hooks Build a todo app Implement drag selection Style with Tailwind CSS Add dark mode support Write unit tests Deploy to production Add keyboard shortcuts Improve accessibility Add animations ```tsx +import React from 'react'; +import { Card, Badge, useDragSelect } from '@vuer-ai/vuer-uikit'; + +const TODOS = [ + { key: "1", title: "Learn React hooks" }, + { key: "2", title: "Build a todo app" }, + { key: "3", title: "Implement drag selection" }, + // ... more items +]; + +export default function DragSelectExample() { + const { selectedItems, getItemProps, clearSelection } = useDragSelect(); + + return ( +
+ + + {TODOS.map(todo => ( + + ))} +
+ ); +} +``` + +## Simple API + +The useDragSelect() hook provides everything you need for drag selection: + +Returns: + +- selectedItems: Set - Currently selected item IDs +- getItemProps(id: string) - Props to spread on selectable items +- clearSelection() - Function to clear all selections +- isSelected(id: string) - Check if item is selected + +Usage: +Just import the hook, call it, and spread getItemProps(id) on your items. The hook handles all the complex state management, event handling, and keyboard shortcuts automatically. + +## Features + +- Automatic Event Handling - Mouse and keyboard events handled internally +- Modifier Key Support - Ctrl/Cmd for replace mode, default toggle mode +- Global Events - Mouse up and Escape key work anywhere on page +- TypeScript Support - Fully typed hook and props +- Zero Dependencies - Pure React implementation + +## Selection Modes + +- Toggle (default): Items flip their selection state during drag +- Replace (Ctrl/Cmd + drag): Clear existing selection, start new selection range + +## Accessibility + +- Semantic HTML structure +- Keyboard navigation support +- Screen reader friendly markup +- Clear visual feedback for selection states \ No newline at end of file diff --git a/docs/components/toggle-buttons.md b/docs/components/toggle-buttons.md new file mode 100644 index 0000000..b2b141c --- /dev/null +++ b/docs/components/toggle-buttons.md @@ -0,0 +1,231 @@ +1. Home +2. Components +3. Toggle Buttons + +# Toggle Buttons + +A set of buttons where only one can be selected at a time, with smooth animated transitions between selections. + +## Props + +### ToggleButtons + +| Prop | Type | Default | Description | +| --- | --- | --- | --- | +| value | string | - | Controlled value | +| onValueChange | (value: string) => void | - | Callback when value changes | +| size | 'sm' | 'base' | 'lg' | 'base' | Size of the buttons | +| variant | 'primary' | 'secondary' | 'ghost' | 'secondary' | Visual style variant | +| padding | boolean | true | Whether to add padding between container and buttons | +| className | string | - | Custom CSS classes | +| children | ReactNode | - | ToggleButton components | + +### ToggleButton + +| Prop | Type | Default | Description | +| --- | --- | --- | --- | +| value | string | - | Value for this button | +| icon | boolean | false | If true, renders as square icon button with proper sizing | +| asChild | boolean | false | Render as child element (using Slot) | +| className | string | - | Custom CSS classes | +| children | ReactNode | - | Button content | + +## Icon Only + +Perfect for toolbar-style interfaces with square buttons: + +Primary + +Secondary + +Ghost + +Selected: select + +```jsx +import { MousePointer, Hand, Scissors } from "lucide-react"; + +const [selectedTool, setSelectedTool] = useState("select"); + +return ( +
+
+

Primary

+ + + + + + + + + + + +
+ +
+

Secondary

+ + + + + + + + + + + +
+ +
+

Ghost

+ + + + + + + + + + + +
+
+); +``` + +## Usage + +Select Pick Cut Selected: select + +```jsx +const [selectedTool, setSelectedTool] = useState("select"); + +return ( + + Select + Pick + Cut + +); +``` + +## Padding Options + +Control the spacing between the container and buttons: + +With Padding (default) + +Select Pick Cut Without Padding + +Select Pick Cut Selected: select + +```jsx +const [selectedTool, setSelectedTool] = useState("select"); + +return ( + <> + {/* With padding (default) */} + + Select + Pick + Cut + + + {/* Without padding - buttons inherit full container size */} + + Select + Pick + Cut + + +); +``` + +## Sizes + +Small + +Select Pick Cut Base + +Select Pick Cut Large + +Select Pick Cut Selected: select + +```jsx +const [selectedTool, setSelectedTool] = useState("select"); + +return ( + <> + + Select + Pick + Cut + + + + Select + Pick + Cut + + + + Select + Pick + Cut + + +); +``` + +## Custom Styling + +Select Pick Cut Selected: select + +```jsx +const [selectedTool, setSelectedTool] = useState("select"); + +return ( + + + Select + + Pick + Cut + +); +``` + +## AsChild + +Use asChild to render the toggle button as a different element while maintaining all functionality: + +[Home](#home)[About](#about)[Contact](#contact)Selected: home + +```jsx +const [selectedPage, setSelectedPage] = useState("home"); + +return ( + + + Home + + + About + + + Contact + + +); +``` \ No newline at end of file diff --git a/docs/components/toggle-group.md b/docs/components/toggle-group.md new file mode 100644 index 0000000..1f0eb72 --- /dev/null +++ b/docs/components/toggle-group.md @@ -0,0 +1,110 @@ +1. Home +2. Components +3. Toggle Group + +# Toggle Group + +A set of two-state buttons that can be toggled on or off. Toggle buttons share outer rounded corners with sharp inner corners, creating a seamless single-button appearance. + +[Docs](https://www.radix-ui.com/primitives/docs/components/toggle-group)[API Reference](https://www.radix-ui.com/primitives/docs/components/toggle-group#api-reference)## Props + +### ToggleGroup + +| Prop | Type | Default | Description | +| --- | --- | --- | --- | +| etype | 'single' | 'multiple' | 'single' | Selection behavior | +| variant | 'primary' | 'secondary' | 'ghost' | 'primary' | Visual style passed to items | +| size | 'sm' | 'base' | 'lg' | 'base' | Size passed to items | +| ...Radix props | ComponentProps | - | All Radix group props | + +### ToggleGroupItem + +| Prop | Type | Default | Description | +| --- | --- | --- | --- | +| inherits | variant, size from group | - | Styling context from parent | +| ...Radix props | ComponentProps | - | All Radix item props | + +Multiple buttons can be active at once with etype="multiple". + +## Variants + +### Primary (Default) + +1 2 3 Selected: option-1 + +```jsx + + 1 + 2 + 3 + +``` + +### Secondary + +1 2 3 Selected: option-1 + +```jsx + + 1 + 2 + 3 + +``` + +### Ghost + +1 2 3 Selected: option-1 + +```jsx + + 1 + 2 + 3 + +``` + +## Single Selection + +Selected: center + +```jsx +const [value, setValue] = useState("center"); + + + + + + + +``` + +Only one button can be active at a time with etype="single". + +## With Icons + +Selected: list + +```jsx +const [value, setValue] = useState(["view-1"]); + + + + + + +``` + +Toggle group with icon content. + +## Disabled State + +1 2 3 Selected: None + +```jsx + + 1 + 2 + 3 + +``` \ No newline at end of file diff --git a/docs/components/toggle.md b/docs/components/toggle.md new file mode 100644 index 0000000..19b5d11 --- /dev/null +++ b/docs/components/toggle.md @@ -0,0 +1,82 @@ +1. Home +2. Components +3. Drag Selectable + +# Drag Selectable + +A React component system that enables drag selection over a vertical list of items with toggle-based multi-select behavior. + +## Live Example + +Try the drag selection below: + +- Normal drag: Toggle selection +- Ctrl/Cmd + drag: Replace selection +- Escape: Clear all selections + +0 item s selected Clear All Learn React hooks Build a todo app Implement drag selection Style with Tailwind CSS Add dark mode support Write unit tests Deploy to production Add keyboard shortcuts Improve accessibility Add animations ```tsx +import React from 'react'; +import { Card, Badge, useDragSelect } from '@vuer-ai/vuer-uikit'; + +const TODOS = [ + { key: "1", title: "Learn React hooks" }, + { key: "2", title: "Build a todo app" }, + { key: "3", title: "Implement drag selection" }, + // ... more items +]; + +export default function DragSelectExample() { + const { selectedItems, getItemProps, clearSelection } = useDragSelect(); + + return ( +
+ + + {TODOS.map(todo => ( + + ))} +
+ ); +} +``` + +## Simple API + +The useDragSelect() hook provides everything you need for drag selection: + +Returns: + +- selectedItems: Set - Currently selected item IDs +- getItemProps(id: string) - Props to spread on selectable items +- clearSelection() - Function to clear all selections +- isSelected(id: string) - Check if item is selected + +Usage: +Just import the hook, call it, and spread getItemProps(id) on your items. The hook handles all the complex state management, event handling, and keyboard shortcuts automatically. + +## Features + +- Automatic Event Handling - Mouse and keyboard events handled internally +- Modifier Key Support - Ctrl/Cmd for replace mode, default toggle mode +- Global Events - Mouse up and Escape key work anywhere on page +- TypeScript Support - Fully typed hook and props +- Zero Dependencies - Pure React implementation + +## Selection Modes + +- Toggle (default): Items flip their selection state during drag +- Replace (Ctrl/Cmd + drag): Clear existing selection, start new selection range + +## Accessibility + +- Semantic HTML structure +- Keyboard navigation support +- Screen reader friendly markup +- Clear visual feedback for selection states \ No newline at end of file diff --git a/docs/components/tooltip.md b/docs/components/tooltip.md new file mode 100644 index 0000000..0d6ce25 --- /dev/null +++ b/docs/components/tooltip.md @@ -0,0 +1,46 @@ +1. Home +2. Components +3. Tooltip + +# Tooltip + +A popup that displays information related to an element when the element receives keyboard focus or the mouse hovers over it. + +[Docs](https://www.radix-ui.com/primitives/docs/components/tooltip)[API Reference](https://www.radix-ui.com/primitives/docs/components/tooltip#api-reference)## Props + +### Tooltip + +| Prop | Type | Default | Description | +| --- | --- | --- | --- | +| ...Radix props | ComponentProps | - | All Radix tooltip root props | + +### TooltipContent + +| Prop | Type | Default | Description | +| --- | --- | --- | --- | +| sideOffset | number | 0 | Offset in pixels from the trigger | +| ...Radix props | ComponentProps | - | All Radix content props | + +## Usage + +Top Left Right Bottom ```jsx + + + + + +

Add to library

+
+
+``` + +### Example + +```jsx + + + + + Hello + +``` \ No newline at end of file diff --git a/docs/components/tree-view.md b/docs/components/tree-view.md new file mode 100644 index 0000000..8288137 --- /dev/null +++ b/docs/components/tree-view.md @@ -0,0 +1,98 @@ +1. Home +2. Components +3. Simple Tree View + +# SimpleTreeView + +## Types + +```typescript +interface TreeDataItem { + id: string; + name: string; + icon?: IconComponent; + selectedIcon?: IconComponent; + openIcon?: IconComponent; + children?: TreeDataItem[]; + actions?: ReactNode; + onClick?: () => void; + draggable?: boolean; + droppable?: boolean; + disabled?: boolean; +} + +type IconComponent = React.ComponentType<{ className?: string }>; +``` + +# Simple Tree View + +## Props + +### SimpleTreeView + +| Prop | Type | Description | +| --- | --- | --- | +| data | `TreeDataItem[] | TreeDataItem` | +| initialSelectedItemId | string | Preselect an item and auto-expand ancestors | +| onSelectChange | (item?: TreeDataItem) => void | Callback when selection changes | +| expandAll | boolean | Expand all nodes initially | +| defaultNodeIcon | IconComponent | Default icon for nodes | +| defaultLeafIcon | IconComponent | Default icon for leaves | +| onDocumentDrag | (source: TreeDataItem, target: TreeDataItem) => void | Drag and drop callback | + +### TreeDataItem + +```ts +type TreeDataItem = { + id: string; + name: string; + icon?: ComponentType>; + selectedIcon?: ComponentType>; + openIcon?: ComponentType>; + children?: TreeDataItem[]; + actions?: React.ReactNode; + onClick?: () => void; + draggable?: boolean; + droppable?: boolean; + disabled?: boolean; +} +``` + +- Item 1 +- Item 2 +- Item 3 + +```jsx +const data = [ + { id: '1', name: 'Item 1', icon: ArrowRight, + children: [ + { id: '2', name: 'Item 1.1', icon: AlarmClock, + children: [ + { id: '3', name: 'Item 1.1.1', icon: Ambulance }, + { id: '4', name: 'Item 1.1.2', icon: Angry }, + ], + }, + { id: '5', name: 'Item 1.2 (disabled)', icon: Album, disabled: true }, + ], + }, { + id: '6', name: 'Item 2', + children: [ + { id: '7', name: 'Item 2.1', icon: AlignCenterHorizontal }, + { id: '8', name: 'Item 2.2', icon: Blend, + children: [ + { id: '9', name: 'Item 2.2.1', icon: Bird }, + { id: '10', name: 'Item 2.2.2', icon: Biohazard, + children: [ + { id: '11', name: 'Item 2.2.2.1', icon: Cannabis }, + { id: '12', name: 'Item 2.2.2.2 Item 2.2.2.2 Item 2.2.2.2 Item 2.2.2.2 Item 2.2.2.2', icon: Cannabis } + ] + }, + ], + }, + ], + }, + { id: '13', name: 'Item 3' } +]; + + +``` \ No newline at end of file diff --git a/docs/components/version-badge.md b/docs/components/version-badge.md new file mode 100644 index 0000000..7d0c60e --- /dev/null +++ b/docs/components/version-badge.md @@ -0,0 +1,88 @@ +1. Home +2. Components +3. Version Badge + +# Version Badge + +Displays the package version with git commit hash. Includes both a high-level component with boolean flags and a low-level component for custom values. + +## High-Level Component (UIKitBadge) + +Uses boolean flags to control which parts of the badge are displayed. All flags default to false - pass them as true to enable each element. + +vuer-uikit [v0.0.117](https://www.npmjs.com/package/@vuer-ai/vuer-uikit/v/0.0.117)[2a52049](https://github.com/vuer-ai/vuer-uikit/commit/2a52049)vuer-uikit [v0.0.117](https://www.npmjs.com/package/@vuer-ai/vuer-uikit/v/0.0.117)vuer-uikit 0.0.1172a52049v0.0.117vuer-uikit 2a520490.0.117```jsx +// Full badge with all elements + + +// Package, version with prefix, clickable (no hash) + + +// Package, version without prefix, with hash + + +// Version with prefix only + + +// Package and hash only (no version) + + +// Version only (no prefix) + +``` + +### Props + +| Prop | Type | Default | Description | +| --- | --- | --- | --- | +| package | boolean | false | Show package name | +| version | boolean | false | Show version number | +| prefix | boolean | false | Add "v" prefix to version | +| hash | boolean | false | Show git commit hash | +| linkable | boolean | false | Make badge clickable (links to npm/github) | +| className | string | - | Additional CSS classes | + +## Low-Level Component (PackageBadge) + +Takes explicit values for full customization. + +custom [v1.2.3](https://www.npmjs.com/package/@org/custom-package/v/1.2.3)[abc123](https://github.com/vuer-ai/vuer-uikit/commit/abc123)mylib 2.0.0v3.0.0-beta.1[def456](https://github.com/vuer-ai/vuer-uikit/commit/def456)```jsx +// Custom package with all values + + +// Non-linkable custom badge + + +// Version and hash only + +``` + +### Props + +| Prop | Type | Default | Description | +| --- | --- | --- | --- | +| packageName | string | - | Package name to display | +| packageFullName | string | - | Full npm package name for link | +| versionText | string | - | Version string to display | +| gitHash | string | - | Git commit hash to display | +| linkable | boolean | true | Make badge clickable | +| className | string | - | Additional CSS classes | + +## Programmatic Access + +```jsx +import { PACKAGE_VERSION, GIT_HASH } from '@vuer-ai/vuer-uikit'; + +console.log(`Version: ${PACKAGE_VERSION}, Commit: ${GIT_HASH}`); +``` \ No newline at end of file diff --git a/docs/components/waterfall.md b/docs/components/waterfall.md new file mode 100644 index 0000000..6876112 --- /dev/null +++ b/docs/components/waterfall.md @@ -0,0 +1,312 @@ +1. Home +2. Components +3. Waterfall + +# Waterfall + +A hierarchical log display component for showing time-based log data with interactive controls and custom actions. + +```typescript +interface WaterfallProps { + logData: LogItemType[]; + temporalCursor?: number; + panelWidth?: number; + onTemporalCursorChange?: (time: number) => void; + getIcon: (item: LogItemType) => ReactNode; + hoveredId?: string | null; + onItemHover?: (id: string | null) => void; + minWindow?: number; + maxWindow?: number; + zoomFactor?: number; + enabled?: boolean; + children?: React.ReactNode; + className?: string; +} +``` + +## Types + +```typescript +type LogItemType = TreeDataItemV2 & { + type: "task" | "attempt" | "info" | "step"; + icon?: "history" | "file-code" | "bot" | "check-circle" | "pause-circle"; + createTime?: number; + startTime?: number; + duration?: number; + time?: number; + color?: "blue" | "green" | "orange" | "gray-light" | "gray-medium" | "purple"; + isCollapsible?: boolean; + hasStripes?: boolean; + isHaltedStep?: boolean; +}; + +type TreeDataItemV2 = { + id: string; + parentId: string | null; + label: string; + isCollapsible?: boolean; + actions?: ReactNode; + disable?: boolean; + [key: string]: unknown; +}; +``` + +## Basic Usage + +Job registered in queue generate-report Attempt 1 Fetch database records Job halted, waiting for resources... Waiting for image renderer... Render charts Assemble PDF Fetch database records Memory checkpoint data-validation Schema validation Data integrity check Generate validation report Cache cleared email-notification Prepare email template Attach report files Send via SMTP Webhook triggered System health check cleanup-process Remove temporary files Update job status All tasks completed -10s -5s 0ms 5s 10s 15s 20s 25s 30s 20.000s 19.900s 3.000s Halted 4.600s 6.200s 3.000s 12.000s 3.500s 33.000s ```jsx +import { Waterfall, LogItemType } from "@vuer-ai/vuer-uikit"; +import React, { useState, useMemo } from "react"; +import { + Bot, + CheckCircle2, + FileCode, + History, + Info, + PauseCircle, + Eye, + EyeClosed, + Trash2, +} from "lucide-react"; +import { cn } from "@vuer-ai/vuer-uikit"; + +const logData: LogItemType[] = [ + { + id: "0", + parentId: null, + indent: 0, + etype: "info", + label: "Job registered in queue", + icon: "history", + time: 0, + color: "purple", + }, + { + id: "1", + parentId: null, + indent: 0, + etype: "task", + label: "generate-report", + icon: "file-code", + createTime: 0, + startTime: 0, + duration: 20, + color: "blue", + isCollapsible: true, + hasStripes: true, + }, + { + id: "2", + parentId: "1", + indent: 1, + etype: "attempt", + label: "Attempt 1", + icon: "bot", + createTime: 0.1, + startTime: 0.1, + duration: 19.9, + color: "blue", + isCollapsible: true, + }, + { + id: "3", + parentId: "2", + indent: 2, + etype: "step", + label: "Fetch database records", + icon: "check-circle", + createTime: 0.2, + startTime: 0.5, + duration: 3, + color: "green", + }, + { + id: "4", + parentId: "2", + indent: 2, + etype: "step", + label: "Job halted, waiting for resources...", + icon: "pause-circle", + startTime: 4, + duration: 2, + color: "orange", + isHaltedStep: true, + }, + // ... more log items +]; + +const getIcon = (item: LogItemType) => { + const iconColor = (item: LogItemType) => { + if (item.label === "generate-report" || item.label === "Assemble PDF") + return "text-blue-500"; + if (item.icon === "file-code") return "text-muted-foreground"; + return ""; + }; + + switch (item.icon) { + case "history": + return ; + case "file-code": + return ; + case "bot": + return ; + case "check-circle": + return ; + case "pause-circle": + return ; + default: + return ; + } +}; + +// Helper functions +const getAllChildrenIds = (parentId: string, allItems: LogItemType[]): string[] => { + const children: string[] = []; + const directChildren = allItems.filter(item => item.parentId === parentId); + + for (const child of directChildren) { + children.push(child.id); + children.push(...getAllChildrenIds(child.id, allItems)); + } + + return children; +}; + +const isIndirectlyHidden = (itemId: string, hiddenItems: Set, allItems: LogItemType[]): boolean => { + const item = allItems.find(i => i.id === itemId); + if (!item || !item.parentId) return false; + + if (hiddenItems.has(item.parentId)) { + return true; + } + + return isIndirectlyHidden(item.parentId, hiddenItems, allItems); +}; + +// State management +const [expandedItems, setExpandedItems] = useState(new Set(["1", "2"])); +const [hoveredId, setHoveredId] = useState(null); +const [hiddenItems, setHiddenItems] = useState>(new Set()); +const [deletedItems, setDeletedItems] = useState>(new Set()); + +// Toggle visibility function +const toggleItemVisibility = (itemId: string) => { + const wasHidden = hiddenItems.has(itemId); + + setHiddenItems(prev => { + const newSet = new Set(prev); + if (newSet.has(itemId)) { + newSet.delete(itemId); + } else { + newSet.add(itemId); + } + return newSet; + }); + + // If hiding an expanded item, collapse it + if (!wasHidden && expandedItems.has(itemId)) { + setExpandedItems(prev => { + const newSet = new Set(prev); + newSet.delete(itemId); + return newSet; + }); + } +}; + +// Delete item function +const deleteItem = (itemId: string) => { + const itemsToDelete = [itemId, ...getAllChildrenIds(itemId, logData)]; + + setDeletedItems(prev => { + const newSet = new Set(prev); + itemsToDelete.forEach(id => newSet.add(id)); + return newSet; + }); + + setHiddenItems(prev => { + const newSet = new Set(prev); + itemsToDelete.forEach(id => newSet.delete(id)); + return newSet; + }); + + setExpandedItems(prev => { + const newSet = new Set(prev); + itemsToDelete.forEach(id => newSet.delete(id)); + return newSet; + }); +}; + +// Create actions for each item +const createActions = (itemId: string, isDirectlyHidden: boolean, isIndirectlyHiddenItem: boolean, isHovered: boolean) => { + const visibilityButton = ( + + ); + + const deleteButton = ( + + ); + + return ( +
+ {isHovered && deleteButton} + {visibilityButton} +
+ ); +}; + +// Process log data with actions and visibility states +const processedLogData = useMemo(() => { + return logData + .filter(item => !deletedItems.has(item.id)) + .map(item => { + const isDirectlyHidden = hiddenItems.has(item.id); + const isIndirectlyHiddenItem = isIndirectlyHidden(item.id, hiddenItems, logData); + const isItemHidden = isDirectlyHidden || isIndirectlyHiddenItem; + const isHovered = hoveredId === item.id; + + return { + ...item, + actions: createActions(item.id, isDirectlyHidden, isIndirectlyHiddenItem, isHovered), + disable: isItemHidden, + isSelectable: !isItemHidden, + }; + }); +}, [logData, deletedItems, hiddenItems, hoveredId]); + +return ( +
+ +
+); +``` \ No newline at end of file diff --git a/docs/dial/api-notes.md b/docs/dial/api-notes.md new file mode 100644 index 0000000..a76554a --- /dev/null +++ b/docs/dial/api-notes.md @@ -0,0 +1,197 @@ +1. [Home](/) +1. [Dial](/dial) +1. Api Notes + +# API Design and Building Blocks + + +## DialPanel Component + + +The `DialPanel` component renders dial controls based on schemas. It accepts the following props: + + +### Props + + +| Prop | Type | Default | Description | +| `schemas` | `DialSchema[]` | Required | Array of dial schemas to render | +| `groups` | `DialGroupConfig[]` | `undefined` | Optional group configurations | +| `labelLayout` | `LabelPositionT` | `undefined` | Default label position layout for all inputs ("top", "left", "right", "inline", etc.) | + + + +### Label Position Priority + + +The label position for inputs is determined by the following priority order: + + + +1. **Component-specific**: Label position tags on individual properties (highest priority) + +- `@dial-label-top`, `@dial-label-left`, `@dial-label-right`, `@dial-label-inline` + + + + + +1. **Panel labelLayout**: `labelLayout` prop on DialPanel + +1. **Component default**: Individual input component's default behavior (lowest priority) + + + +### Example Usage + + +```tsx +import { DialPanel, DialProvider } from '@vuer-ai/vuer-uikit'; + +// With default label layout for all inputs + + + + +// Without specifying (components use their own defaults) + + + + +``` + + +Individual components can still override the panel's default label layout: + + +```tsx +interface Props { + /** + * @dial-label-left // This overrides the panel's labelLayout + */ + specialField: number; +} + +``` + + +## Building Blocks + + +We want to specify the property menu without duplicating the code. Here are the basic building blocks: + + +| Control Entry | Control Group | +| ```jsx +const controlEntry = { +dtype: 'number', +value: 10, +min: 0, +max: 100, +step: 1, +} + +``` + + | ```jsx +const controlGroup = { +tag: 'group', +children: [ +controlEntry, +], +layout: 'row', +} + +``` + + | + + + +Now, let's convert this into a react schema that we can create using react.createElement: + + +```jsx + + + + + + + + +``` + + +this can be written via react createElement below: + + +```jsx +React.createElement( + Dial.Provider, + null, + React.createElement( + Dial.Row, + null, + React.createElement(DialInput, { + label: "Position", + column: true, + type: "number", + key: "prop-name", + value: 10, + min: 0, + max: 100, + step: 1 + }), + React.createElement(DialInput, { + label: "Rotation", + column: true, + type: "number", + key: "prop-name", + value: 10, + min: 0, + max: 100, + step: 1 + }), + React.createElement(DialInput, { + label: "Scale", + column: true, + type: "number", + key: "prop-name", + value: 10, + min: 0, + max: 100, + step: 1 + }) + ) +) + +``` + + +We can do this via a nested json object using a convenient helper function: + + +```jsx +function build({tag, children, ...props}) { + return React.createElement(tag, props, children) +} + +``` + + +We can then rewrite the schema as: + + +```jsx +{ name: 'position', dtype: 'vector3', value: [0, 0, 0], min: 0, max: 100, options: [10, 20, 30, 40, 50], + tags: { grouping: 'transform', col: true } } +{ name: 'rotation', dtype: 'euler', value: [0, 0, 0], min: 0, max: 100, options: [10, 20, 30, 40, 50], + tags: { grouping: 'transform', col: true } } +{ name: 'scale', dtype: 'vector3', value: [1, 1, 1], min: 0, max: 100, options: [10, 20, 30, 40, 50], + tags: { grouping: 'transform', col: true } } + +``` diff --git a/docs/dial/cli-details.md b/docs/dial/cli-details.md new file mode 100644 index 0000000..8b4c49d --- /dev/null +++ b/docs/dial/cli-details.md @@ -0,0 +1,777 @@ +1. [Home](/) +1. [Dial](/dial) +1. Cli Details + +# Dial CLI Reference + + +The `dial-cli` tool is a powerful command-line utility for generating UI schemas from TypeScript interfaces with Dial annotations. This page provides a complete reference for all CLI features and options. + + +## Installation + + +The dial-cli is now available as a standalone package for cleaner installation: + + +```bash +# Install globally (recommended for CLI tools) +npm install -g @vuer-ai/dial-cli +# or +pnpm install -g @vuer-ai/dial-cli + +# Or install as a dev dependency +npm install --save-dev @vuer-ai/dial-cli +# or +pnpm add -D @vuer-ai/dial-cli + +``` + + +Once installed, the CLI is available directly: + + +```bash +# If installed globally +dial-cli --help + +# If installed as dev dependency +npx dial-cli --help + +``` + + +### Benefits of Standalone Package + + + +- **Minimal dependencies** - Only includes what's needed for CLI operation (typescript, react-docgen-typescript) + +- **No peer dependency warnings** - Doesn't require React, Tailwind, or other UI dependencies + +- **Smaller install size** - ~32KB unpacked vs entire UI kit + +- **Independent versioning** - CLI updates don't require UI kit updates + + + +## Command Line Options + + +### Basic Usage + + +```bash +dial-cli [options] + +``` + + +### Options Reference + + +| Option | Alias | Description | Default | +| `--output ` | `-o` | Output directory for generated files | `./metadata` | +| `--verbose` | | Enable verbose output with detailed information | `false` | +| `--quiet` | | Suppress all output except errors | `false` | +| `--remove` | | Remove generated metadata files | `false` | +| `--ignore ` | `-i` | Comma-separated list of properties to ignore | - | +| `--help` | `-h` | Display help information | - | +| `--version` | `-v` | Display version information | - | + + + +### Verbose Mode + + +The `--verbose` flag enables detailed output and generates additional files: + + +```bash +dial-cli --verbose MyComponent.tsx + +``` + + +In verbose mode, dial-cli generates: + + + +- `schema.dial` - Combined dial schema for all components (main output) + +- `debug/` - Debug directory containing: + +- `component-raw.json` - Raw docgen output + +- `component-combined.json` - Enhanced metadata + +- `component-schemas.json` - Component schemas + + + + + + + +**Note:** Debug files are organized in a `debug/` subdirectory to keep the main output clean. These files are only generated in verbose mode and are useful for debugging schema generation issues. + + +### Quiet Mode + + +The `--quiet` flag suppresses all output except errors, useful for CI/CD: + + +```bash +dial-cli --quiet src/components/*.tsx + +``` + + +### Remove Mode + + +The `--remove` flag cleans up generated metadata files: + + +```bash +# Remove metadata for specific component +dial-cli --remove MyComponent.tsx + +# Remove all metadata in output directory +dial-cli --remove --output ./metadata + +``` + + +**Important:** The remove command cleans up both the main `schema.dial` file and any debug files in the `debug/` directory. It supports both the current debug directory structure and legacy file locations for backward compatibility. + + +### Ignore Properties + + +Exclude specific properties from schema generation: + + +```bash +# Ignore single property +dial-cli --ignore ref MyComponent.tsx + +# Ignore multiple properties +dial-cli --ignore "ref,key,children" MyComponent.tsx + +# Using short alias +dial-cli -i "internalProp,debugValue" Component.tsx + +``` + + +## Output Files + + +### Standard Output (Default) + + +Without verbose mode, only generates: + + + +- `schema.dial` - Combined schema for all processed components + + + +### Verbose Output + + +With `--verbose` flag, generates additional files per component: + + + +- `[component]-schemas.json` - Component-specific schema + +- `[component]-raw.json` - Raw react-docgen output + +- `[component]-combined.json` - Enhanced metadata with dial annotations + +- `schema.dial` - Combined schema (always generated) + + + +## Group-Level Configuration + + +You can apply configuration to entire groups of properties using interface-level JSDoc comments: + + +### Using @dial-no-wrap + + +The `@dial-no-wrap` annotation prevents line wrapping for all properties in a group: + + +```tsx +interface ComponentProps { + /** + * Layout configuration for transform properties + * @dial transform @dial-no-wrap + */ + + /** @dial transform @dial-dtype vector3 */ + position: number[]; + + /** @dial transform @dial-dtype euler */ + rotation: number[]; + + /** @dial transform @dial-dtype vector3 */ + scale: number[]; +} + +``` + + +In this example, all properties in the "transform" group (position, rotation, scale) will be displayed on a single line without wrapping. + + +### Groups in Output Schema + + +The CLI now generates a `groups` section in the output schema: + + +```json +{ + "component": "ExampleBox", + "schema": [...], + "groups": [ + { + "name": "transform", + "noWrap": true + } + ] +} + +``` + + +This allows the UI to apply group-specific styling and layout configuration. + + +## Excluding Properties + + +There are two ways to exclude properties from dial schema generation: + + +### 1. Using @dial-ignore Annotation + + +Add `@dial-ignore` to any property's JSDoc comment to exclude it from the generated schema: + + +```tsx +interface ComponentProps { + /** + * Public property - included in schema + * @dial transform + * @dial-dtype vector3 + */ + position: number[]; + + /** + * Internal state - excluded from schema + * @dial-ignore + */ + _internalCache?: any; + + /** + * React ref - excluded from schema + * @dial-ignore + */ + ref?: React.Ref; +} + +``` + + +### 2. Using CLI --ignore Option + + +The `-i` or `--ignore` option allows you to exclude properties by name or pattern at runtime: + + +```bash +# Exclude specific properties +dial-cli -i className -i style Component.tsx + +# Exclude using comma-separated list +dial-cli --ignore ref,key,id Component.tsx + +# Exclude using glob patterns +dial-cli -i "*Style" -i "on*" -i "_*" Component.tsx + +``` + + +#### Glob Pattern Examples + + +| Pattern | Matches | Example Properties | +| `*Style` | Ends with "Style" | `containerStyle`, `buttonStyle`, `textStyle` | +| `on*` | Starts with "on" | `onClick`, `onChange`, `onSubmit` | +| `_*` | Starts with underscore | `_internal`, `_cache`, `_private` | +| `*Ref` | Ends with "Ref" | `inputRef`, `containerRef`, `buttonRef` | +| `data*` | Starts with "data" | `dataSource`, `dataProvider`, `dataKey` | + + + +## Class/Interface Level Suppression + + +The `@dial-ignore` annotation can be used at the class or interface level to completely suppress dial schema generation for an entire component and all its properties: + + +```tsx +/** + * Internal configuration component + * @dial-ignore + */ +interface InternalSettingsProps { + apiKey: string; + debugMode: boolean; + serverUrl: string; + // All properties will be excluded from dial schema +} + +/** + * Admin-only component + * @dial-ignore + */ +export const AdminPanel: FC = ({ ... }) => { + // This component won't appear in dial UI +} + +``` + + +This is useful for: + + + +- Internal/utility components that shouldn't be exposed in the UI + +- Admin-only or developer-only components + +- Components that are still under development + +- Helper components that are only used internally + + + +When `@dial-ignore` is used at the class/interface level: + + + +- The entire component is skipped during dial schema generation + +- No properties from that component will appear in the dial UI + +- Any child properties or nested interfaces are also excluded + + + +## Custom Property Labels + + +The `@dial-label` annotation allows you to specify custom labels for properties that will be displayed in the UI instead of the default auto-generated labels from the property name: + + +```tsx +interface ComponentProps { + /** + * Position in 3D space + * @dial transform + * @dial-dtype vector3 + * @dial-label 3D Position + */ + pos3d: [number, number, number]; + + /** + * Background color + * @dial appearance + * @dial-dtype color + * @dial-label Background Color + */ + bgColor: string; + + /** + * Enable shadows + * @dial-dtype boolean + * @dial-label Enable Shadow Rendering + */ + shadowsOn: boolean; +} + +``` + + +In the generated UI: + + + +- `pos3d` will display as "3D Position" instead of "Pos3d" + +- `bgColor` will display as "Background Color" instead of "BgColor" + +- `shadowsOn` will display as "Enable Shadow Rendering" instead of "ShadowsOn" + + + +This is particularly useful when property names follow coding conventions (camelCase, abbreviations) but you want more user-friendly labels in the UI. + + +## Complete Example + + +Here's a complete example showing exclusion methods and custom labels: + + +### Component Definition + + +```tsx +// Box3D.tsx +interface Box3DProps { + /** + * Box dimensions + * @dial geometry + * @dial-dtype vector3 + * @dial-min 0.1 + * @dial-max 10 + * @dial-step 0.1 + */ + size: [number, number, number]; + + /** + * Position in 3D space + * @dial transform + * @dial-dtype vector3 + * @dial-min -100 + * @dial-max 100 + * @dial-step 0.5 + */ + position: [number, number, number]; + + /** + * Material color + * @dial appearance + * @dial-dtype color + */ + color: string; + + /** + * Opacity level + * @dial appearance + * @dial-min 0 + * @dial-max 1 + * @dial-step 0.01 + */ + opacity: number; + + // Properties to exclude: + + /** + * Internal mesh reference + * @dial-ignore + */ + _meshRef?: THREE.Mesh; + + /** + * React className - will be excluded via CLI + */ + className?: string; + + /** + * React style - will be excluded via CLI + */ + style?: React.CSSProperties; + + /** + * Click handler - will be excluded via CLI pattern + */ + onClick?: () => void; + + /** + * Change handler - will be excluded via CLI pattern + */ + onChange?: (value: any) => void; +} + +``` + + +### CLI Commands + + +```bash +# Generate schema excluding React-specific props and handlers +dial-cli -i className -i style -i "on*" Box3D.tsx + +# Or using comma-separated list +dial-cli --ignore className,style,onClick,onChange Box3D.tsx + +# Exclude all private properties and event handlers +dial-cli -i "_*" -i "on*" Box3D.tsx + +``` + + +### Generated Schema + + +The generated schema will only include: + + + +- `size` - Box dimensions control + +- `position` - Position control + +- `color` - Color picker + +- `opacity` - Opacity slider + + + +Excluded properties: + + + +- `_meshRef` - Excluded by `@dial-ignore` annotation + +- `className`, `style` - Excluded by CLI `-i` option + +- `onClick`, `onChange` - Excluded by CLI pattern `"on*"` + + + +## CLI Options Reference + + +```bash +dial-cli [options] + +``` + + +### Options + + +| Option | Short | Description | Example | +| `--output ` | `-o` | Output directory for generated files | `-o ./schemas` | +| `--ignore ` | `-i` | Properties to exclude (supports glob) | `-i className -i "on*"` | +| `--verbose` | | Enable verbose output | `--verbose` | +| `--quiet` | | Suppress output except errors | `--quiet` | +| `--help` | `-h` | Display help message | `--help` | +| `--version` | `-v` | Display version | `--version` | + + + +## Output Files + + +The CLI generates files with a clean directory structure: + + +**Main Output:** + + + +- **`schema.dial`** - Combined schemas for all components, ready for UI generation + + + +**Debug Output (verbose mode only):** + + + +- **`debug/component-raw.json`** - Raw AST and JSDoc extraction + +- **`debug/component-combined.json`** - Enhanced metadata with dial schemas + +- **`debug/component-schemas.json`** - Individual component schemas + + + +This structure keeps your main output directory clean while providing detailed debug information when needed. + + +## Best Practices + + +### 1. Combine Both Exclusion Methods + + +Use `@dial-ignore` for properties that should never be exposed in the UI: + + +```tsx +/** + * @dial-ignore + */ +_internalState?: any; + +``` + + +Use CLI `--ignore` for context-specific exclusions: + + +```bash +# Exclude React-specific props when generating for non-React environments +dial-cli -i className -i style Component.tsx + +``` + + +### 2. Use Patterns for Consistency + + +Create consistent naming conventions and use patterns: + + +```bash +# Exclude all private properties, refs, and handlers +dial-cli -i "_*" -i "*Ref" -i "on*" Component.tsx + +``` + + +### 3. Create Build Scripts + + +Add scripts to your `package.json`: + + +```json +{ + "scripts": { + "dial:generate": "dial-cli -o ./schemas -i className,style,key,ref src/components/*.tsx", + "dial:generate:clean": "dial-cli -o ./schemas -i '_*,on*,*Ref,className,style' src/components/*.tsx" + } +} + +``` + + +### 4. Document Excluded Properties + + +When using `@dial-ignore`, add a comment explaining why: + + +```tsx +/** + * Internal cache for performance optimization + * Not meant to be modified by users + * @dial-ignore + */ +_cache?: Map; + +``` + + +## Integration Example + + +Here's how to use the generated schemas in your application: + + +```tsx +import { DialProvider, DialPanel } from '@vuer-ai/vuer-uikit'; +import allSchemas from './schemas/schema.dial'; + +function App() { + const [props, setProps] = useState({ + size: [1, 1, 1], + position: [0, 0, 0], + color: '#ff0000', + opacity: 1 + }); + + const handleValueChange = (name: string, value: any) => { + setProps(prev => ({ ...prev, [name]: value })); + }; + + // Get the specific component schema from the combined schema file + const box3DSchema = allSchemas.find(s => s.component === 'Box3D'); + + return ( + +
+ + + + +
+
+ ); +} + +``` + + +## Troubleshooting + + +### Properties Not Being Excluded + + + +1. **Check annotation syntax**: Ensure `@dial-ignore` is on its own line + +1. **Check pattern syntax**: Use quotes for patterns with wildcards: `-i "*Style"` + +1. **Check property names**: Property names are case-sensitive + + + +### Generated Schema Is Empty + + + +1. Ensure your interface has JSDoc comments with `@dial` annotations + +1. Check that the TypeScript file exports the interface + +1. Verify the file path is correct + + + +### Build Errors + + + +1. Ensure `@vuer-ai/dial-cli` is installed + +1. Try using the full path: `node_modules/.bin/dial-cli` (if installed locally) + +1. Check Node.js version (requires Node 14+) + + + +## Summary + + +The dial-cli tool provides flexible property exclusion through: + + + +- **`@dial-ignore` annotation** - Permanent, code-level exclusion + +- **`--ignore` CLI option** - Runtime, context-specific exclusion + +- **Glob patterns** - Flexible pattern-based exclusion + + + +Combine these features to create clean, focused UI schemas that expose only the properties users need to control. diff --git a/docs/dial/controlled-dials.md b/docs/dial/controlled-dials.md new file mode 100644 index 0000000..eed1d2a --- /dev/null +++ b/docs/dial/controlled-dials.md @@ -0,0 +1,187 @@ +1. [Home](/) +1. [Dial](/dial) +1. Controlled Dials + +# Controlled Dials + + +The `DialProvider` component supports both controlled and uncontrolled modes, giving you flexibility in how you manage dial state. + + +## Simple 3D Object Example + + +transformPositionxyzRenderOrderResetExamplePosition: [0.0, 5.0, 0.0]Render Order: 0```jsx +const schemas = [ + { + name: "position", + dtype: "vector3", + value: [1, 2, 3], + //... + } +]; + +const [values, setValues] = useState({ + position: [0, 5, 0], + renderOrder: 0 +}); + + +const handleChange = (name, value) => { + setValues(prev => ({ ...prev, [name]: value })); +}; + +return ( + + + +); + +``` + + +## Full Schema Example from JSON + + +FooBar Object PropertiestransformPositionxyzRotationxyzScalexyzdisplayVisibleOpacityReset All``` +{ + "position": [ + 0, + 5, + 0 + ], + "rotation": [ + 0, + 0, + 0 + ], + "scale": [ + 1, + 1, + 1 + ], + "visible": true, + "opacity": 1 +} +``` + +```jsx +// Schema data structure (could be loaded from JSON) +const schemaData = { + "FooBar": { + "schemas": [ + { + "name": "position", + "dtype": "vector3", + "value": [0, 5, 0], + "min": -10, + "max": 10, + "step": 0.1, + "tags": { + "grouping": "transform", + "noWrap": true + } + }, + // ... more schemas + ] + } +}; + +// Initialize values from schemas +const [values, setValues] = useState(() => { + const initial = {}; + schemaData.FooBar.schemas.forEach(schema => { + initial[schema.name] = schema.value; + }); + return initial; +}); + +const handleChange = (name, value) => { + setValues(prev => ({ ...prev, [name]: value })); +}; + +return ( + + + +); + +``` + + +## API Reference + + +### DialProvider Props + + +| Prop | Type | Description | +| `schemas` | `DialSchema[]` | Array of dial schemas defining the dials | +| `values` | `Record` | Current values for controlled mode | +| `initialValues` | `Record` | Initial values for uncontrolled mode | +| `onValueChange` | `(name: string, value: DialValue) => void` | Callback when values change | +| `children` | `ReactNode` | Child components | + + + +### Schema Structure + + +```typescript +interface DialSchema { + name: string; // Unique identifier + dtype: string; // "number", "boolean", "vector3", "select", etc. + value?: any; // Default value + min?: number; // For number/vector inputs + max?: number; // For number/vector inputs + step?: number; // Step size for number/vector inputs + options?: string[]; // For select inputs + tags?: { + grouping?: string; // Group related controls + noWrap?: boolean; // Prevent wrapping in group + // ... other tags + }; +} + +``` + + +### Common Data Types + + + +- **`number`**: Single numeric value + +- **`boolean`**: True/false toggle + +- **`vector3`**: 3D vector [x, y, z] + +- **`select`**: Dropdown with options + +- **`string`**: Text input + + + +### Grouping with Tags + + +The `tags.grouping` property allows you to organize related controls together. Controls with the same `grouping` value will be visually grouped in the UI. + + +```json +{ + "tags": { + "grouping": "transform", + "noWrap": true + } +} + +``` diff --git a/docs/dial/getting-started.md b/docs/dial/getting-started.md new file mode 100644 index 0000000..8ebf1de --- /dev/null +++ b/docs/dial/getting-started.md @@ -0,0 +1,129 @@ +# Getting Started with Dial + +## Overview + +Dial is a schema-driven system that "parses JSDoc annotations in your TypeScript/React components" and then "generates UI schemas that describe controls and their properties." + +The system automates interactive control creation from TypeScript interfaces, supporting complex types like vectors, tuples, and nested objects. + +## Installation + +Install the CLI tool using your package manager: + +```bash +# Global installation +pnpm install -g @vuer-ai/dial-cli + +# Or as a dev dependency +pnpm add -D @vuer-ai/dial-cli +``` + +## Basic Workflow + +### Step 1: Annotate Your Component + +Add JSDoc comments with `@dial` tags to your TypeScript component properties: + +```typescript +interface BoxProps { + /** + * Box dimensions + * @dial geometry + * @dial-dtype vector3 + * @dial-min 0.1 + * @dial-max 10 + * @dial-step 0.1 + */ + size: [number, number, number]; + + /** + * Material color + * @dial appearance + * @dial-dtype color + */ + color: string; + + /** + * Visibility toggle + * @dial visibility + * @dial-dtype boolean + */ + visible: boolean; + + /** + * Opacity level + * @dial appearance + * @dial-dtype number + * @dial-min 0 + * @dial-max 1 + * @dial-step 0.01 + */ + opacity: number; +} +``` + +### Step 2: Generate the Schema + +```bash +dial-cli Box.tsx +# Outputs: metadata/schema.dial +``` + +### Step 3: Use the Generated Schema + +```typescript +import { DialProvider, DialPanel } from '@vuer-ai/vuer-uikit'; +import allSchemas from './metadata/schema.dial'; + +function App() { + const boxSchema = allSchemas.find(s => s.component === 'Box'); + + return ( + + + + ); +} +``` + +## Core Annotation Tags + +| Tag | Purpose | +|-----|---------| +| `@dial ` | Groups related properties together | +| `@dial-dtype ` | Specifies control data type | +| `@dial-min/max/step` | Sets numeric constraints | +| `@dial-icon ` | Adds Lucide icon to control | +| `@dial-ignore` | Excludes property from schema | + +## Supported Data Types + +| Type | Purpose | Example | +|------|---------|---------| +| `number` | Basic numeric input | `42` | +| `boolean` | Toggle switch | `true/false` | +| `string` | Text input | `"hello"` | +| `color` | Color picker | `"#ff0000"` | +| `vector3` | 3D vector | `[1, 2, 3]` | +| `euler` | Rotation angles | `[0, 90, 180]` | +| `select` | Dropdown menu | `"option1"` | + +## Property Grouping + +Organize properties by adding the same group name across multiple fields: + +```typescript +interface Props { + /** @dial transform */ + position: [number, number, number]; + + /** @dial transform */ + rotation: [number, number, number]; + + /** @dial appearance */ + color: string; + + /** @dial appearance */ + metalness: number; +} +``` diff --git a/docs/dial/input-types.md b/docs/dial/input-types.md new file mode 100644 index 0000000..701ee01 --- /dev/null +++ b/docs/dial/input-types.md @@ -0,0 +1,1113 @@ +1. [Home](/) +1. [Dial](/dial) +1. Input Types + +# Dial Input Types + + + +Input Types Referencedial-cli[v0.0.22](https://www.npmjs.com/package/@vuer-ai/dial-cli/v/0.0.22) +The Dial system supports a comprehensive set of input types for different data formats and use cases. Each input type has specific properties and behaviors optimized for its data type. + + +## Live Examples + + +### Quick Start Example + + +SpeedDirection°Active```jsx +const schemas = [ + { name: 'speed', dtype: 'number', value: 50, min: 0, max: 100 }, + { name: 'direction', dtype: 'number-rad', value: 0 }, + { name: 'active', dtype: 'boolean', value: true }, +]; + + + + + +``` + + +### Basic Types Example + + +UsernameAgeScoreAngle°Enabled**Values:** {}```jsx +const [values, setValues] = useState({}); + +const schemas = [ + { name: 'username', dtype: 'string', value: 'John Doe' }, + { name: 'age', dtype: 'number-int', value: 25, min: 0, max: 120 }, + { name: 'score', dtype: 'number', value: 85.5, min: 0, max: 100, step: 0.5 }, + { name: 'angle', dtype: 'number-rad', value: Math.PI / 4, step: 15 }, + { name: 'enabled', dtype: 'boolean', value: true }, +]; + +const handleValueChange = (name, value) => { + setValues(prev => ({ ...prev, [name]: value })); +}; + + + + + +``` + + +### Vector and Rotation Types Example + + +TransformPositionxyzRotationx°y°z°RotationRadx°y°z°Scalexyz**Values:**``` +{} +``` + +```jsx +const schemas = [ + { + name: 'position', + dtype: 'vector3', + value: [0, 1, 0], + min: -10, + max: 10, + step: 0.1, + tags: { grouping: 'Transform', noWrap: true } + }, + { + name: 'rotation', + dtype: 'euler', + value: [0, 45, 0], + step: 15, + tags: { grouping: 'Transform', noWrap: true } + }, + { + name: 'rotationRad', + dtype: 'euler-rad', + value: [0, Math.PI/4, 0], + step: 15, + tags: { grouping: 'Transform', noWrap: true } + }, + { + name: 'scale', + dtype: 'vector3', + value: [1, 1, 1], + min: 0.1, + max: 5, + step: 0.1, + tags: { grouping: 'Transform', noWrap: true } + } +]; + +const groups = [ + { name: 'Transform', noWrap: true } +]; + + + + + +``` + + +### Selection and Color Types Example + + +AppearanceThemelightQuality123BackgroundColor#Opacity0.8**Current Values:**``` +{} +``` + +```jsx +const schemas = [ + { + name: 'theme', + dtype: 'string', + value: 'light', + options: ['light', 'dark', 'auto'], + tags: { grouping: 'Appearance' } + }, + { + name: 'quality', + dtype: 'number', + value: 2, + options: [ + { label: 'Low', value: 1 }, + { label: 'Medium', value: 2 }, + { label: 'High', value: 3 }, + ], + tags: { grouping: 'Appearance' } + }, + { + name: 'backgroundColor', + dtype: 'color', + value: '#3b82f6', + tags: { grouping: 'Appearance' } + }, + { + name: 'opacity', + dtype: 'number-slider', + value: 0.8, + min: 0, + max: 1, + step: 0.1, + tags: { grouping: 'Appearance' } + } +]; + + + + + +``` + + +### Advanced Layout Example + + +DimensionsWidthHeightPhysicsVelocityxyzForcexyz```jsx +const schemas = [ + // Inline label examples + { + name: 'width', + dtype: 'number', + value: 100, + min: 0, + max: 500, + tags: { grouping: 'Dimensions', labelPosition: 'inline' } + }, + { + name: 'height', + dtype: 'number', + value: 100, + min: 0, + max: 500, + tags: { grouping: 'Dimensions', labelPosition: 'inline' } + }, + // Vector with no wrap + { + name: 'velocity', + dtype: 'vector3', + value: [0, 0, 0], + min: -100, + max: 100, + step: 0.1, + tags: { grouping: 'Physics', noWrap: true } + }, + { + name: 'force', + dtype: 'vector3', + value: [0, -9.8, 0], + min: -50, + max: 50, + step: 0.1, + tags: { grouping: 'Physics', noWrap: true } + } +]; + +const groups = [ + { name: 'Dimensions', noWrap: false }, + { name: 'Physics', noWrap: true } +]; + + + + + +``` + + +## Basic Input Types + + +### string + + +Standard text input for string values. + + +```tsx +/** + * @dial-dtype string + * @dial-icon Text + */ +name: string; + +``` + + +**Features:** + + + +- Single-line text input + +- Supports placeholder text + +- Can be used with icons + + + +### number + + +Numeric input with optional constraints and drag-to-adjust functionality. + + +```tsx +/** + * @dial-dtype number + * @dial-min 0 + * @dial-max 100 + * @dial-step 0.1 + */ +value: number; + +``` + + +**Features:** + + + +- Numeric validation + +- Min/max bounds + +- Step increment control + +- **Drag to adjust**: Click and drag vertically on the input to change values + +- Drag up to increase, down to decrease + +- Hold Shift for fine control (10x slower) + +- Respects min/max constraints + +- Maintains step precision + + + + + +- Can also type values directly + + + +### number-int + + +Integer-only numeric input. + + +```tsx +/** + * @dial-dtype number-int + * @dial-min 0 + * @dial-max 10 + * @dial-step 1 + */ +count: number; + +``` + + +**Features:** + + + +- Integer validation + +- Whole number steps only + +- Typically rendered as stepper or slider + + + +### number-rad + + +Numeric input for radian values displayed as degrees. + + +```tsx +/** + * @dial-dtype number-rad + * @dial-step 15 // Step of 15 degrees + */ +angle: number; // Stored as radians, displayed as degrees + +``` + + +**Features:** + + + +- Single angle input + +- Value stored internally as radians + +- Displayed and edited in degrees for user convenience + +- Automatic degree-to-radian conversion + +- Useful for single rotation axes + + + +### boolean + + +Toggle switch for boolean values. + + +```tsx +/** + * @dial-dtype boolean + * @dial-icon Eye + */ +visible: boolean; + +``` + + +**Features:** + + + +- Toggle switch UI + +- Optional icon display + +- Clear on/off states + + + +## Vector Types + + +### vector2 + + +Two-component vector for 2D coordinates. + + +```tsx +/** + * @dial-dtype vector2 + * @dial-min -10 + * @dial-max 10 + * @dial-step 0.1 + */ +position2D: [number, number]; + +``` + + +**Features:** + + + +- Two numeric inputs (X, Y) + +- Individual component constraints + +- Compact horizontal layout + + + +### vector3 + + +Three-component vector for 3D coordinates. + + +```tsx +/** + * @dial-dtype vector3 + * @dial-min -100 + * @dial-max 100 + * @dial-step 0.01 + * @dial-icon Move3d + */ +position: [number, number, number]; + +``` + + +**Features:** + + + +- Three numeric inputs (X, Y, Z) + +- Component labels and tooltips + +- Can be displayed in row or column layout + +- Per-component min/max/step values + + + +### vector4 + + +Four-component vector for quaternions or RGBA values. + + +```tsx +/** + * @dial-dtype vector4 + * @dial-min 0 + * @dial-max 1 + * @dial-step 0.01 + */ +quaternion: [number, number, number, number]; + +``` + + +**Features:** + + + +- Four numeric inputs + +- Useful for quaternions, colors with alpha + +- Compact layout options + + + +## Rotation Types + + +### euler + + +Euler angles for 3D rotation (in degrees). + + +```tsx +/** + * @dial-dtype euler + * @dial-min -180 + * @dial-max 180 + * @dial-step 1 + * @dial-icon RotateCw + */ +rotation: [number, number, number]; + +``` + + +**Features:** + + + +- Three angle inputs (X, Y, Z) + +- Degree-based input + +- Circular wrapping (-180 to 180) + +- Rotation-specific icons + + + +### euler-rad + + +Euler angles stored in radians but displayed in degrees for better UX. + + +```tsx +/** + * @dial-dtype euler-rad + * @dial-step 15 // Step of 15 degrees + * @dial-icon RotateCw + */ +rotation: [number, number, number]; // Values stored as radians + +``` + + +**Features:** + + + +- Three angle inputs (X, Y, Z) + +- Values stored internally as radians + +- Displayed and edited in degrees for user convenience + +- Automatic degree-to-radian conversion + + + +### quaternion + + +Quaternion representation for 3D rotation. + + +```tsx +/** + * @dial-dtype quaternion + */ +rotationQuat: [number, number, number, number]; + +``` + + +**Features:** + + + +- Four component inputs (X, Y, Z, W) + +- Normalized values + +- Advanced rotation representation + + + +## Color Types + + +### color + + +Color picker with various format support. + + +```tsx +/** + * @dial-dtype color + * @dial-icon Palette + */ +backgroundColor: string; + +``` + + +**Features:** + + + +- Color picker UI + +- Hex, RGB, HSL support + +- Alpha channel option + +- Preset color swatches + + + +### rgb + + +RGB color as three components. + + +```tsx +/** + * @dial-dtype rgb + * @dial-min 0 + * @dial-max 255 + * @dial-step 1 + */ +rgbColor: [number, number, number]; + +``` + + +**Features:** + + + +- Three sliders (R, G, B) + +- 0-255 range + +- Live color preview + + + +## Selection Types + + +### select + + +Dropdown selection from predefined options. + + +```tsx +/** + * @dial-dtype select + * @dial-options ["option1", "option2", "option3"] + * @dial-icon List + */ +mode: string; + +``` + + +**Features:** + + + +- Dropdown menu + +- Predefined options + +- Single selection + +- Optional icons for items + + + +### enum + + +Enumerated values with labeled options. + + +```tsx +/** + * @dial-dtype enum + * @dial-options [ + * { label: "Small", value: "sm" }, + * { label: "Medium", value: "md" }, + * { label: "Large", value: "lg" } + * ] + */ +size: string; + +``` + + +**Features:** + + + +- Radio buttons or dropdown + +- Label/value pairs + +- Type-safe selections + + + +## Array Types + + +### array + + +Dynamic array of values. + + +```tsx +/** + * @dial-dtype array + * @dial-dtype-element number + * @dial-min 0 + * @dial-max 100 + */ +values: number[]; + +``` + + +**Features:** + + + +- Add/remove items + +- Per-element constraints + +- Reorderable items + +- Batch operations + + + +### vector + + +Generic vector with configurable size. + + +```tsx +/** + * @dial-dtype vector + * @dial-size 6 + * @dial-min -1 + * @dial-max 1 + * @dial-step 0.01 + */ +weights: number[]; + +``` + + +**Features:** + + + +- Fixed or dynamic size + +- Uniform constraints + +- Compact multi-input layout + + + +## Special Types + + +### matrix3 + + +3x3 transformation matrix. + + +```tsx +/** + * @dial-dtype matrix3 + */ +transform2D: number[][]; + +``` + + +**Features:** + + + +- 3x3 grid layout + +- Matrix-specific operations + +- Visual matrix representation + + + +### matrix4 + + +4x4 transformation matrix. + + +```tsx +/** + * @dial-dtype matrix4 + */ +transform3D: number[][]; + +``` + + +**Features:** + + + +- 4x4 grid layout + +- Homogeneous coordinates + +- 3D transformation support + + + +### json + + +JSON object editor. + + +```tsx +/** + * @dial-dtype json + * @dial-icon Code + */ +config: object; + +``` + + +**Features:** + + + +- Syntax-highlighted editor + +- JSON validation + +- Tree view option + +- Schema validation support + + + +### file + + +File path or file upload. + + +```tsx +/** + * @dial-dtype file + * @dial-accept ".jpg,.png,.gif" + * @dial-icon FileImage + */ +imagePath: string; + +``` + + +**Features:** + + + +- File picker dialog + +- Drag and drop support + +- File type filtering + +- Path or base64 output + + + +## Layout Modifiers + + +### Column Layout + + +Display vector inputs in columns. + + +```tsx +/** + * @dial-dtype vector3 + * @dial-col-3 + */ +dimensions: [number, number, number]; + +``` + + +### Row Layout + + +Display inputs horizontally. + + +```tsx +/** + * @dial-dtype vector2 + * @dial-row + */ +coordinates: [number, number]; + +``` + + +### No Wrap + + +Prevent line wrapping for grouped inputs. + + +```tsx +/** + * @dial transform @dial-no-wrap + */ + +``` + + +### Label Position + + +Control label placement. + + +```tsx +/** + * @dial-dtype number + * @dial-label-inline + */ +opacity: number; + +``` + + +## Type-Specific Annotations + + +### Numeric Constraints + + +```tsx +@dial-min // Minimum value +@dial-max // Maximum value +@dial-step // Step increment +@dial-precision // Decimal places + +``` + + +### Vector Constraints + + +```tsx +@dial-mins [, ...] // Per-component minimums +@dial-maxs [, ...] // Per-component maximums +@dial-steps [, ...] // Per-component steps +@dial-placeholders [, ...] // Component labels + +``` + + +### Selection Options + + +```tsx +@dial-options [...] // Array of options +@dial-default // Default selection +@dial-multiple // Allow multiple selections + +``` + + +### Display Options + + +```tsx +@dial-icon // Lucide icon name +@dial-tooltip // Hover tooltip +@dial-placeholder // Input placeholder +@dial-disabled // Disable input +@dial-readonly // Read-only mode + +``` + + +## Best Practices + + + +1. +**Choose the right type**: Use specific types like `vector3` instead of generic `array` for better UI. + + + + +1. +**Set appropriate constraints**: Always define min/max/step for numeric inputs. + + + + +1. +**Group related properties**: Use `@dial ` to organize related controls. + + + + +1. +**Use semantic icons**: Choose icons that represent the property's purpose. + + + + +1. +**Provide tooltips**: Add helpful descriptions for complex properties. + + + + +1. +**Consider layout**: Use row/column modifiers for better space utilization. + + + + + + +## Examples + + +### Complete 3D Object Properties + + +```tsx +interface Object3DProps { + /** @dial transform @dial-dtype vector3 @dial-icon Move3d */ + position: [number, number, number]; + + /** @dial transform @dial-dtype euler @dial-icon RotateCw */ + rotation: [number, number, number]; + + /** @dial transform @dial-dtype vector3 @dial-min 0.01 @dial-icon Scaling */ + scale: [number, number, number]; + + /** @dial appearance @dial-dtype color @dial-icon Palette */ + color: string; + + /** @dial appearance @dial-dtype number @dial-min 0 @dial-max 1 */ + opacity: number; + + /** @dial visibility @dial-dtype boolean @dial-icon Eye */ + visible: boolean; +} + +``` + + +### Material Properties + + +```tsx +interface MaterialProps { + /** @dial appearance @dial-dtype color */ + diffuseColor: string; + + /** @dial appearance @dial-dtype color */ + specularColor: string; + + /** @dial appearance @dial-dtype number @dial-min 0 @dial-max 1 */ + roughness: number; + + /** @dial appearance @dial-dtype number @dial-min 0 @dial-max 1 */ + metalness: number; + + /** @dial textures @dial-dtype file @dial-accept ".jpg,.png" */ + diffuseMap: string; + + /** @dial textures @dial-dtype file @dial-accept ".jpg,.png" */ + normalMap: string; +} + +``` + + +## Next Steps + + + +- Learn about the [Dial Annotation Syntax](/dial/overview) + +- Follow the [Tutorial](/dial/tutorial) to implement Dial in your project + +- See [Controlled Dials](/dial/controlled-dials) for programmatic control + +- Check [API Notes](/dial/api-notes) for detailed API reference diff --git a/docs/dial/overview.md b/docs/dial/overview.md new file mode 100644 index 0000000..e8ec7eb --- /dev/null +++ b/docs/dial/overview.md @@ -0,0 +1,60 @@ +# Dial: A Schema-Driven Menu System + +## Overview + +Dial represents a system that generates user interface controls automatically from TypeScript interfaces using JSDoc annotations. This approach eliminates manual UI creation by defining control properties directly in code comments. + +## Core Annotation Syntax + +The system uses JSDoc comments to specify UI behavior: + +**Grouping Controls:** +- `@dial ` organizes related properties +- `@dial @dial-no-wrap` applies group-level settings + +**Property Configuration:** +- `@dial- ` sets control attributes using hyphen notation +- `@dial-col-` arranges elements in n-column layouts +- `@dial-dtype ` specifies data types (vector3, euler, boolean, int, etc.) +- `@dial-min ` and `@dial-max ` establish value bounds +- `@dial-step ` defines increment sizes +- `@dial-options [...]` provides preset values +- `@dial-icon ` assigns Lucide icon names +- `@dial-label ` customizes property display names +- `@dial-ignore` excludes properties from schema generation + +## Example Implementation + +A TypeScript interface can be annotated to define a 3D box geometry with transformation controls: + +```typescript +interface ExampleBoxProps { + args: ExampleBoxArgs; + position: number[] | null; + rotation: number[] | null; + scale: number[] | null; + hide: boolean; + alphaTest: boolean; + depthTest: boolean; + renderOrder: number; + _internalState?: any; +} +``` + +Annotations specify constraints, groupings, and visual representation for each property. + +## Key Features + +**Schema-Driven Architecture:** UI controls generate automatically from annotated TypeScript code, eliminating manual interface creation. + +**Grouped Layout System:** Properties organize automatically into sections based on their grouping annotations. + +**Integrated State Management:** Built-in state tracking with value change callbacks enables seamless application integration. + +## Next Steps + +- **Tutorial:** Step-by-step guide for using dial-cli +- **Input Types:** Complete reference of supported input types +- **Controlled Dials:** Advanced usage patterns +- **API Notes:** Detailed API reference +- **CLI Details:** Advanced command-line options diff --git a/docs/dial/testing.md b/docs/dial/testing.md new file mode 100644 index 0000000..73bd1d9 --- /dev/null +++ b/docs/dial/testing.md @@ -0,0 +1,443 @@ +1. [Home](/) +1. [Dial](/dial) +1. Testing + +# Testing Dial Annotations + + + +Testing Guidedial-cli[v0.0.22](https://www.npmjs.com/package/@vuer-ai/dial-cli/v/0.0.22) +This guide covers testing strategies for Dial annotations, running the dial-cli test suite, and contributing to dial-cli development. + + +## Testing Your Dial Annotations + + +### 1. Validate Generated Schemas + + +After annotating your components, validate the generated schemas: + + +```bash +# Generate with verbose output for inspection +dial-cli --verbose MyComponent.tsx + +# Check the generated files +cat metadata/schema.dial | jq '.' + +``` + + +### 2. Common Validation Checks + + +#### Check Property Types + + +Ensure properties have the correct dtype: + + +```json +{ + "name": "position", + "dtype": "vector3", // Should match your annotation + "value": [0, 0, 0] +} + +``` + + +#### Verify Constraints + + +Check min/max/step values are applied: + + +```json +{ + "name": "opacity", + "dtype": "number", + "min": 0, + "max": 1, + "step": 0.01 +} + +``` + + +#### Validate Grouping + + +Ensure properties are correctly grouped: + + +```json +{ + "name": "rotation", + "dtype": "euler", + "tags": { + "grouping": "transform" + } +} + +``` + + +### 3. Test Type Inheritance + + +When using interface inheritance or type intersections: + + +```bash +# Generate schema for inherited types +dial-cli --verbose ExtendedComponent.tsx + +# Verify all parent properties are included +jq '.[] | select(.component == "ExtendedComponent") | .schemas[].name' \ + metadata/schema.dial + +``` + + +### 4. Automated Testing + + +Create a test script to validate your schemas: + + +```javascript +// test-dial-schemas.js +const fs = require('fs'); +const schema = require('./metadata/schema.dial'); + +describe('Dial Schemas', () => { + test('should have required properties', () => { + const component = schema.find(c => c.component === 'MyComponent'); + expect(component).toBeDefined(); + + const propNames = component.schemas.map(s => s.name); + expect(propNames).toContain('position'); + expect(propNames).toContain('rotation'); + expect(propNames).toContain('scale'); + }); + + test('should have correct types', () => { + const component = schema.find(c => c.component === 'MyComponent'); + const position = component.schemas.find(s => s.name === 'position'); + + expect(position.dtype).toBe('vector3'); + expect(position.value).toHaveLength(3); + }); + + test('should inherit group configurations', () => { + const component = schema.find(c => c.component === 'AnimatedBox'); + const duration = component.schemas.find(s => s.name === 'duration'); + + expect(duration.tags?.noWrap).toBe(true); + }); +}); + +``` + + +## Running Dial CLI Tests + + +The dial-cli package includes a comprehensive test suite for validation. + + +### Prerequisites + + +```bash +# Navigate to dial-cli directory +cd packages/vuer-uikit/dial-cli + +# Install dependencies +pnpm install + +# Build the CLI +pnpm build + +``` + + +### Running Tests + + +```bash +# Run all tests +pnpm test + +# Run tests in watch mode for development +pnpm test:watch + +# Run tests with coverage +pnpm test:coverage + +``` + + +### Test Output + + +Successful test run shows: + + +``` +PASS spec/inheritance.test.ts + dial-cli inheritance tests + Interface Inheritance + ✓ should resolve properties from extended interfaces + ✓ should handle deep inheritance chains + Type Inheritance + ✓ should resolve properties from type intersections + ✓ should handle utility types (Pick, Omit, Partial) + Mixed Inheritance + ✓ should handle interface extending type + ✓ should handle type intersecting interface + Group configurations + ✓ should inherit group-level @dial-no-wrap + dial-cli remove functionality + ✓ should remove specific component metadata + ✓ should remove all metadata files + +Test Suites: 1 passed, 1 total +Tests: 9 passed, 9 total + +``` + + +## Contributing to Dial CLI + + +### Development Setup + + + +1. **Fork and Clone** + + + +```bash +git clone https://github.com/your-username/vuer-uikit.git +cd vuer-uikit/packages/vuer-uikit/dial-cli + +``` + + + +1. **Install Dependencies** + + + +```bash +pnpm install + +``` + + + +1. **Start Development Mode** + + + +```bash +pnpm dev +# This watches for changes and rebuilds automatically + +``` + + +### Writing New Tests + + +Tests are located in the `spec/` directory: + + +``` +spec/ +├── inheritance.test.ts # Main test suite +├── fixtures/ # Test TypeScript files +│ ├── InterfaceInheritance.tsx +│ ├── TypeInheritance.tsx +│ └── MixedInheritance.tsx +└── outputs/ # Expected outputs for comparison + +``` + + +#### Adding a Test Case + + +```typescript +// spec/inheritance.test.ts +test('should handle new feature', () => { + const fixture = join(FIXTURES_DIR, 'NewFeature.tsx'); + + // Generate schema + execSync(`node "${DIAL_CLI}" --verbose --output "${OUTPUT_DIR}" "${fixture}"`); + + // Read and validate + const schemaPath = join(OUTPUT_DIR, 'schema.dial'); + const schemas = JSON.parse(readFileSync(schemaPath, 'utf-8')); + + // Assertions + expect(schemas).toBeDefined(); + expect(schemas[0].component).toBe('NewFeature'); +}); + +``` + + +#### Creating Test Fixtures + + +```tsx +// spec/fixtures/NewFeature.tsx +import React from 'react'; + +/** + * Test component for new feature + * @dial config @dial-new-feature + */ +interface NewFeatureProps { + /** + * Test property + * @dial config + * @dial-dtype string + * @dial-new-annotation value + */ + testProp: string; +} + +export const NewFeature: React.FC = ({ testProp }) => { + return
{testProp}
; +}; + +``` + + +### Running Tests During Development + + +```bash +# Run specific test file +pnpm test inheritance.test.ts + +# Run tests matching pattern +pnpm test -- --testNamePattern="type intersection" + +# Run with debugging +NODE_OPTIONS="--inspect" pnpm test + +``` + + +### Debugging Tips + + + +1. **Use Verbose Output** + + + +```bash +dial-cli --verbose TestComponent.tsx +# Check all generated files for debugging + +``` + + + +1. **Inspect AST** +Add debug logging to see TypeScript AST: + + + +```typescript +console.log('AST Node:', node.kind, node.getText()); + +``` + + + +1. **Test Individual Components** + + + +```bash +# Test a specific fixture +node dist/dial-cli.js --verbose spec/fixtures/TypeInheritance.tsx + +``` + + +## Common Issues and Solutions + + +### Issue: Properties Not Appearing in Schema + + +**Cause:** Missing `@dial` annotation +**Solution:** Ensure property has at least one `@dial` tag + + +```tsx +// Won't appear in schema +/** Just a comment */ +prop: string; + +// Will appear in schema +/** @dial control */ +prop: string; + +``` + + +### Issue: Type Inheritance Not Working + + +**Cause:** Types not properly exported or resolved +**Solution:** Ensure all types are exported and accessible + + +```tsx +// Export types for proper resolution +export type BaseType = { ... }; +export interface ExtendedInterface extends BaseType { ... } + +``` + + +### Issue: Group Configuration Not Applied + + +**Cause:** Group-level annotations at wrong position +**Solution:** Place group annotations in interface/type JSDoc + + +```tsx +/** + * @dial transform @dial-no-wrap // Correct position + */ +interface Props { + // Properties here inherit the configuration +} + +``` + + +## Next Steps + + + +- Review [Type Inheritance](/dial/type-inheritance) patterns + +- Check [CLI Reference](/dial/cli-reference) for all options + +- See [Examples](/dial/examples) for real-world usage + +- Read [Troubleshooting](/dial/cli-reference/troubleshooting) for common issues diff --git a/docs/dial/tutorial.md b/docs/dial/tutorial.md new file mode 100644 index 0000000..a18d768 --- /dev/null +++ b/docs/dial/tutorial.md @@ -0,0 +1,374 @@ +1. [Home](/) +1. [Dial](/dial) +1. Tutorial + +# Dial Tutorial: Using dial-cli + + + +Dial CLI Tutorialdial-cli[v0.0.22](https://www.npmjs.com/package/@vuer-ai/dial-cli/v/0.0.22) +This tutorial will guide you through using the dial-cli tool to generate UI controls from TypeScript interfaces with Dial annotations. + + +## Using the dial-cli Tool + + +The `dial-cli` is now available as a standalone package for generating Dial schemas from TypeScript files, providing a cleaner installation experience without UI dependencies. + + +### Installation + + +```bash +# Install globally (recommended for CLI tools) +npm install -g @vuer-ai/dial-cli +# or +pnpm install -g @vuer-ai/dial-cli + +# Check CLI is available +dial-cli --help + +``` + + +### Basic Usage + + +```bash +# Generate schemas from a TypeScript file +dial-cli [input-file2...] + +# Examples: +dial-cli ./src/components/Box.tsx +# Creates schema.dial in ./metadata directory + +dial-cli ./src/components/Box.tsx -o ./schemas +# Outputs to specified directory + +# Process multiple files +dial-cli Component1.tsx Component2.tsx + +# Specify output directory +dial-cli -o ./metadata MyComponent.tsx + +``` + + +### What the CLI Does + + +The dial-cli tool will: + + + +1. Parse your TypeScript file using the TypeScript compiler API + +1. Extract all interfaces and types with Dial annotations + +1. Process JSDoc comments following the `@dial` convention + +1. Generate JSON schema files that can be directly used with DialPanel + + + +### Output Files + + +The CLI generates files with a clean directory structure: + + +**Main Output:** + + + +- `schema.dial` - Combined schemas for all components, ready for UI generation + + + +**Debug Output (verbose mode only):** + + + +- `debug/component-raw.json` - Raw output from react-docgen-typescript + +- `debug/component-combined.json` - Enhanced metadata with dial schema information + +- `debug/component-schemas.json` - Individual component schemas for debugging + + + +### Local Script + + +This documentation includes a convenience script for generating metadata: + + +```bash +# From the dial directory +./generate-dial-metadata.sh + +``` + + +This will process the `BoxExample.tsx` file and output metadata to the `metadata/` directory. + + +## Using Generated Schemas + + +Once you've generated schemas using dial-cli, you can use them in your application. +The Dial system consists of three main components: + + + +1. **DialProvider** - Manages state for all controls + +1. **DialPanel** - Converts schemas to UI components + +1. **Input Components** - Individual control types (number, vector, boolean, etc.) + + + +### Component API + + +**DialPanel** accepts the following props: + + +```tsx +interface DialPanelProps { + schemas: DialSchema[]; // Array of control schemas + groups?: DialGroupConfig[]; // Optional group configurations +} + +``` + + +Usage: + + +```tsx +// Basic usage with just schemas + + +// With group configuration for layout control + + +``` + + +### TypeScript Interfaces + + +The Dial system uses the following main interfaces: + + +```tsx +// Schema for individual controls +interface DialSchema { + name: string; + dtype: string; + value?: DialValue; + min?: number; + max?: number; + step?: number; + options?: Array; + // ... other properties + tags?: { + grouping?: string; + col?: boolean | number; + row?: number; + layout?: string; + labelPosition?: LabelPositionT; + noWrap?: boolean; + }; +} + +// Group configuration for styling and layout +interface DialGroupConfig { + name: string; + noWrap?: boolean; + [key: string]: unknown; +} + +// Complete schema with groups (output from dial-cli) +interface DialSchemaGroup { + component: string; + schema: DialSchema[]; + groups?: DialGroupConfig[]; +} + +// Valid value types +type DialValue = string | number | boolean | number[] | string[] | null | undefined; + +``` + + +```tsx +import { DialProvider, DialPanel } from './dial'; + +const schemas = [ + { + name: 'position', + dtype: 'vector3', + value: [0, 0, 0], + min: -10, + max: 10, + tags: { grouping: 'transform', col: true } + }, + // ... more schemas +]; + +function MyComponent() { + const handleValueChange = (name, value) => { + console.log(`${name} changed to`, value); + }; + + return ( + + + + ); +} + +``` + + +### Complete Example with dial-cli + + + +1. **Create a TypeScript file with Dial annotations:** + + + +```tsx +// Box.tsx +interface BoxProps { + /** + * Transform properties displayed on single line + * @dial transform @dial-no-wrap + */ + + /** @dial transform @dial-dtype vector3 */ + position: [number, number, number]; + + /** @dial transform @dial-dtype euler */ + rotation: [number, number, number]; + + /** + * Box dimensions + * @dial geometry + * @dial-dtype vector3 + * @dial-min 0.1 + * @dial-max 10 + * @dial-step 0.1 + */ + size: [number, number, number]; + + /** + * Box color + * @dial appearance + * @dial-dtype color + */ + color: string; +} + +export const Box: React.FC = ({ size, position, rotation, color }) => { + // Component implementation +}; + +``` + + + +1. **Generate the schema:** + + + +```bash +dial-cli Box.tsx -o ./schemas +# Creates schemas/schema.dial with groups configuration + +``` + + +The generated schema includes group-level settings: + + +```json +{ + "component": "Box", + "schema": [ + { "name": "position", "dtype": "vector3", "tags": { "grouping": "transform", "noWrap": true } }, + { "name": "rotation", "dtype": "euler", "tags": { "grouping": "transform", "noWrap": true } }, + { "name": "size", "dtype": "vector3", "tags": { "grouping": "geometry" } }, + { "name": "color", "dtype": "color", "tags": { "grouping": "appearance" } } + ], + "groups": [ + { "name": "transform", "noWrap": true } + ] +} + +``` + + + +1. **Use the generated schema in your app:** + + + +```tsx +import { DialProvider, DialPanel, DialSchemaGroup, DialValue } from '@vuer-ai/vuer-uikit'; +import allSchemas from './schemas/schema.dial'; + +// Get the Box component schema from the combined schema file +const boxSchema = allSchemas.find(s => s.component === 'Box'); + +function App() { + const [boxProps, setBoxProps] = useState({ + position: [0, 0, 0], + rotation: [0, 0, 0], + size: [1, 1, 1], + color: '#ff0000' + }); + + const handleValueChange = (name: string, value: DialValue) => { + setBoxProps(prev => ({ ...prev, [name]: value })); + }; + + return ( + +
+ {/* Your 3D scene */} + + + {/* Auto-generated controls with group configuration */} + +
+
+ ); +} + +``` + + +## Next Steps + + + +- Learn more about [Dial Annotation Syntax](/dial/overview) in the overview + +- Explore all [Input Types](/dial/input-types) available in Dial + +- See [Controlled Dials](/dial/controlled-dials) for advanced usage + +- Check out the [API Notes](/dial/api-notes) for detailed reference + +- Read the [CLI Details](/dial/cli-details) for advanced CLI options diff --git a/docs/dial/type-inheritance.md b/docs/dial/type-inheritance.md new file mode 100644 index 0000000..55b651a --- /dev/null +++ b/docs/dial/type-inheritance.md @@ -0,0 +1,352 @@ +1. [Home](/) +1. [Dial](/dial) +1. Type Inheritance + +# Type Inheritance in Dial + + + +Type Inheritance & Compositiondial-cli[v0.0.22](https://www.npmjs.com/package/@vuer-ai/dial-cli/v/0.0.22) +Dial CLI fully supports TypeScript's type system, including interface inheritance, type intersections, and utility types. This allows you to create reusable, composable type definitions while maintaining all Dial annotations and configurations. + + +## Interface Inheritance + + +When interfaces extend others, all properties and group configurations are inherited: + + +### Basic Interface Extension + + +```tsx +// Base interface with common properties +interface BaseProps { + /** + * Unique identifier + * @dial common + * @dial-dtype string + */ + id: string; + + /** + * Visibility control + * @dial common + * @dial-dtype boolean + */ + visible: boolean; +} + +// Extended interface inherits all base properties +interface BoxProps extends BaseProps { + /** + * Box dimensions + * @dial geometry + * @dial-dtype vector3 + */ + size: [number, number, number]; + + /** + * Material color + * @dial appearance + * @dial-dtype color + */ + color: string; +} + +// BoxProps will have: id, visible, size, color + +``` + + +### Deep Inheritance Chains + + +```tsx +interface Level1 { + /** @dial level1 */ + prop1: string; +} + +interface Level2 extends Level1 { + /** @dial level2 */ + prop2: number; +} + +interface Level3 extends Level2 { + /** @dial level3 */ + prop3: boolean; +} + +// Level3 has all properties from Level1, Level2, and its own + +``` + + +## Type Intersections + + +Type intersections combine multiple types while preserving all annotations and group configurations: + + +### Basic Type Intersection + + +```tsx +type TransformType = { + /** @dial transform @dial-dtype vector3 */ + position: [number, number, number]; + /** @dial transform @dial-dtype euler */ + rotation: [number, number, number]; +}; + +type AppearanceType = { + /** @dial appearance @dial-dtype color */ + color: string; + /** @dial appearance @dial-dtype number @dial-min 0 @dial-max 1 */ + opacity: number; +}; + +// Combine multiple types +type GameObject = TransformType & AppearanceType & { + /** @dial metadata @dial-dtype string */ + name: string; +}; + +``` + + +### Group Configuration Inheritance + + +The `@dial-no-wrap` configuration is inherited through type intersections: + + +```tsx +/** + * Animation properties that should display on one line + * @dial animation @dial-no-wrap + */ +type AnimationType = { + /** @dial animation @dial-dtype number @dial-min 0 @dial-max 10 */ + duration: number; + + /** @dial animation @dial-dtype string */ + easing: string; + + /** @dial animation @dial-dtype number @dial-min 0 @dial-max 5 */ + delay: number; +}; + +// Properties from AnimationType inherit noWrap: true +type AnimatedObject = BaseType & AnimationType & { + /** @dial control @dial-dtype boolean */ + playing: boolean; +}; + +``` + + +## Utility Types + + +Dial supports TypeScript's built-in utility types: + + +### Pick - Select Specific Properties + + +```tsx +type FullTransform = { + /** @dial position @dial-dtype number */ + x: number; + /** @dial position @dial-dtype number */ + y: number; + /** @dial position @dial-dtype number */ + z: number; + /** @dial rotation @dial-dtype number-deg */ + rotationX: number; + /** @dial rotation @dial-dtype number-deg */ + rotationY: number; + /** @dial rotation @dial-dtype number-deg */ + rotationZ: number; +}; + +// Only position properties +type Position2D = Pick; +// Result: { x: number, y: number } with annotations + +``` + + +### Omit - Exclude Properties + + +```tsx +// Everything except rotation +type TranslateOnly = Omit; +// Result: { x, y, z } with all dial annotations preserved + +``` + + +### Partial - Make Properties Optional + + +```tsx +type RequiredConfig = { + /** @dial config @dial-dtype string */ + apiKey: string; + /** @dial config @dial-dtype string */ + endpoint: string; + /** @dial config @dial-dtype number */ + timeout: number; +}; + +// All properties become optional +type OptionalConfig = Partial; +// Result: { apiKey?: string, endpoint?: string, timeout?: number } + +``` + + +## Property Override + + +Child types can override parent property annotations: + + +```tsx +interface BaseComponent { + /** + * Base color property + * @dial appearance + * @dial-dtype string + */ + color: string; +} + +interface AdvancedComponent extends BaseComponent { + /** + * Enhanced color with picker + * @dial appearance + * @dial-dtype color + * @dial-icon Palette + */ + color: string; // Overrides with color picker +} + +``` + + +## Complex Example + + +Here's a real-world example combining multiple inheritance patterns: + + +```tsx +// Base types with group configs +type PhysicsProps = { + /** @dial physics @dial-dtype number @dial-min 0 @dial-max 100 */ + mass: number; + /** @dial physics @dial-dtype number @dial-min 0 @dial-max 1 */ + friction: number; +}; + +/** + * @dial animation @dial-no-wrap + */ +type AnimationProps = { + /** @dial animation */ + duration: number; + /** @dial animation */ + loop: boolean; +}; + +// Interface extending a type intersection +interface GameObject extends PhysicsProps, AnimationProps { + /** @dial metadata */ + id: string; + /** @dial transform @dial-dtype vector3 */ + position: [number, number, number]; +} + +// Further composition +type InteractiveGameObject = GameObject & { + /** @dial interaction */ + onClick: () => void; + /** @dial interaction @dial-dtype boolean */ + hoverable: boolean; +}; + +// Using utility types +type StaticObject = Omit; +type PreviewObject = Partial; + +``` + + +## Generated Schema + + +The dial-cli correctly resolves all inheritance and generates complete schemas: + + +```json +{ + "component": "InteractiveGameObject", + "schemas": [ + { "name": "mass", "dtype": "number", "min": 0, "max": 100, "tags": { "grouping": "physics" } }, + { "name": "friction", "dtype": "number", "min": 0, "max": 1, "tags": { "grouping": "physics" } }, + { "name": "duration", "dtype": "number", "tags": { "grouping": "animation", "noWrap": true } }, + { "name": "loop", "dtype": "boolean", "tags": { "grouping": "animation", "noWrap": true } }, + { "name": "id", "dtype": "string", "tags": { "grouping": "metadata" } }, + { "name": "position", "dtype": "vector3", "tags": { "grouping": "transform" } }, + { "name": "hoverable", "dtype": "boolean", "tags": { "grouping": "interaction" } } + ], + "groups": [ + { "name": "animation", "noWrap": true } + ] +} + +``` + + +## Best Practices + + + +1. **Use Base Interfaces** for common properties across components + +1. **Group Related Types** with type aliases for reusability + +1. **Apply Group Configs** at the type level for consistent layout + +1. **Document Overrides** when child types change parent behavior + +1. **Test Inheritance** by running dial-cli with `--verbose` to see full resolution + + + +## Limitations + + + +- Generic types with type parameters require concrete types for dial-cli to process + +- Conditional types are not fully supported + +- Mapped types need explicit property definitions + + + +## Next Steps + + + +- Learn about [Group Configurations](/dial/annotations/grouping) for layout control + +- Explore [Advanced Annotations](/dial/annotations/advanced) for complex types + +- See [Complete Examples](/dial/examples) using inheritance patterns diff --git a/docs/form-inputs/input.md b/docs/form-inputs/input.md new file mode 100644 index 0000000..6de6df0 --- /dev/null +++ b/docs/form-inputs/input.md @@ -0,0 +1,95 @@ +# Input Component Documentation + +## Overview + +The Input component represents a fundamental UI element within the toolkit, supporting multiple visual presentations, dimensions, and operational states. + +## Props Configuration + +### InputRoot Properties + +| Property | Type | Default | Purpose | +|----------|------|---------|---------| +| `size` | `'sm' \| 'base' \| 'lg'` | `'base'` | Adjusts input dimensions | +| `state` | `'default' \| 'error'` | `'default'` | Visual feedback styling | +| `side` | `'left' \| 'center' \| 'right'` | — | Text positioning and cursor placement | +| `inputClassName` | `string` | — | Custom classes for inner input element | +| Standard input attributes | `ComponentProps<'input'>` | — | Native HTML input properties | + +### InputSlot Properties + +| Property | Type | Default | Purpose | +|----------|------|---------|---------| +| `side` | `'left' \| 'right'` | `'left'` | Slot positioning | +| Standard div attributes | `ComponentProps<'div'>` | — | Native HTML div properties | + +## Type Definitions + +```typescript +interface InputRootProps extends ComponentProps<"div">, VariantProps { + state?: "default" | "error"; + side?: "left" | "right" | "center"; + asChild?: boolean; + inputClassName?: string; + size?: "sm" | "base" | "lg"; +} + +interface InputSlotProps extends ComponentProps<"div"> { + side?: "left" | "right"; +} +``` + +## Text Alignment Options + +The component accommodates three alignment directions: left (default), center, and right. Slot components enable prefixes and suffixes through positioned elements. + +## State Management + +**Default State**: Standard appearance for typical interactions + +**Error State**: Visual indication for validation failures and user feedback + +**Disabled State**: Prevents user interaction and modification + +## Input Type Examples + +- **Text Input**: Standard character input +- **Number Input**: Numeric values with optional currency symbols +- **Password Input**: Masked character display +- **Email Input**: Email-specific validation +- **Search Input**: Search functionality with supplementary icons + +## Interactive Examples + +### Character Counter Implementation + +```javascript +const [value, setValue] = useState(''); +const [count, setCount] = useState(0); + +return ( + { + setValue(e.target.value); + setCount(e.target.value.length); + }} + /> +); +``` + +### Calculation Feature + +Combines price and quantity inputs for real-time total computation: + +```javascript +const [price, setPrice] = useState(''); +const [quantity, setQuantity] = useState(''); +const total = (parseFloat(price) || 0) * (parseInt(quantity) || 0); +``` + +### Form Validation Pattern + +Implements error detection and submission handling through state management and conditional styling based on validation results. diff --git a/docs/form-inputs/number-inputs.md b/docs/form-inputs/number-inputs.md new file mode 100644 index 0000000..ef476ca --- /dev/null +++ b/docs/form-inputs/number-inputs.md @@ -0,0 +1,154 @@ +# Number Inputs Documentation + +## Overview + +A comprehensive collection of numeric input components with drag-to-modify functionality, specialized inputs for measurements, angles, and multi-dimensional data types. + +## Basic Number Input (InputRoot) + +The fundamental numeric input uses InputRoot with `etype="number"`. Mouse dragging is not supported. + +```jsx +const [value, setValue] = useState(42.5); + + setValue(e.target.value)} + placeholder="Enter a number" +/> +``` + +## InputNumbers (Single) + +Advanced numeric input component with drag-to-modify functionality and enhanced UX. + +```jsx +const [value, setValue] = useState([42.5]); + + +``` + +### Props + +| Prop | Type | Default | Description | +|------|------|---------|-------------| +| `value` | `number[]` | — | Array of numbers for each input | +| `onValuesChange` | `(value: number[]) => void` | — | Callback when values change | +| `step` | `number` | `0.1` | Step size for drag modifications | +| `size` | `'sm' \| 'md' \| 'lg'` | `'md'` | Input size variant | +| `side` | `'left' \| 'center' \| 'right'` | `'left'` | Text alignment | +| `prefix` | `ReactNode[]` | — | Array of prefix labels/units for each input | +| `suffix` | `ReactNode[]` | — | Array of suffix labels/units for each input | + +### Types + +```typescript +interface InputNumbersProps extends Pick { + step?: number; + value: number[]; + prefix?: ReactNode[]; + suffix?: ReactNode[]; + onValuesChange?: (value: Array) => void; +} +``` + +## Text Alignment Options + +InputNumbers supports three text alignment variants: + +**Left aligned (default)** +```jsx +const [leftValue, setLeftValue] = useState([123.45]); + +``` + +**Center aligned** +```jsx +const [centerValue, setCenterValue] = useState([123.45]); + +``` + +**Right aligned** +```jsx +const [rightValue, setRightValue] = useState([123.45]); + +``` + +## Prefix and Suffix Usage + +Add context to inputs with prefixes or suffixes: + +**With prefix ($)** +```jsx +const [price, setPrice] = useState([299.99]); + +``` + +**With suffix (kg)** +```jsx +const [weight, setWeight] = useState([75.5]); + +``` + +## Grouped Inputs + +Multiple numeric inputs grouped together with coordinated drag selection for multi-dimensional data: + +```jsx +const [position, setPosition] = useState([10.5, 20.3, -5.8]); + +``` + +## Drag Interaction Features + +All InputNumbers components support advanced drag interactions: + +- **Vertical drag**: Select multiple inputs by dragging up/down +- **Horizontal drag**: Modify selected values by dragging left/right +- **Modifier keys**: + - `Shift` + drag: 5x step size + - `Alt` + drag: 0.2x step size + +## Related Components + +For specialized input components with built-in units and advanced data types, see the Specialized Input Components documentation. diff --git a/docs/form-inputs/playground.md b/docs/form-inputs/playground.md new file mode 100644 index 0000000..08fa4c1 --- /dev/null +++ b/docs/form-inputs/playground.md @@ -0,0 +1,32 @@ +# Form Inputs Playground + +This page appears to be a **demonstration/showcase page** for the Vuer UIKit form components rather than a documentation article with detailed explanations. + +## Available Components Displayed + +The playground showcases interactive examples of: + +- **Text Input** - with various label positioning options (left, top, with sub-labels) +- **Toggle** - switch control +- **Input Groups** - both vertical and horizontal layouts +- **Textarea** - multi-line text input +- **Selectors** - dropdown/select components +- **Number Inputs** - including: + - Steps (with configurable increments) + - Interval controls +- **Radio Groups** - both vertical and horizontal layouts +- **Preset Inputs** - with values like 10, 20, 30 +- **Color Picker** - with hexadecimal input field + +## Component Variations + +Each component type is presented with multiple configurations: + +- Different label arrangements +- Horizontal and vertical orientations +- Optional sublabel/helper text +- Various state examples + +## Documentation Structure + +This playground appears designed as an **interactive testing ground** rather than a reference guide. The actual implementation details and code examples would be found in the linked documentation pages for each specific input type (Input, Number Inputs, Specialized Inputs). diff --git a/docs/form-inputs/specialized-inputs.md b/docs/form-inputs/specialized-inputs.md new file mode 100644 index 0000000..f1acafa --- /dev/null +++ b/docs/form-inputs/specialized-inputs.md @@ -0,0 +1,115 @@ +# Specialized Input Components Documentation + +## Overview + +Pre-configured numeric input components for common measurement units, angles, and multi-dimensional data types. + +## Common Props + +All specialized input components share these properties: + +| Prop | Type | Default | Purpose | +|------|------|---------|---------| +| `value` | `number` or `number[]` | — | Current value(s) | +| `onChange` / `onValuesChange` | `(value) => void` | — | Callback when values change | +| `size` | `'sm' \| 'md' \| 'lg'` | `'md'` | Input size variant | +| `step` | `number` | varies | Step size for drag modifications | + +### Angle Input Additional Props + +| Prop | Type | Default | Component | +|------|------|---------|-----------| +| `display` | `'rad' \| 'deg' \| 'pi'` | `'rad'` | `RadInput`, `EulerRadInput`, `PresetsRadInput` | +| `presets` | `[number, number, number]` | — | `PresetsRadInput` | + +## Measurement Unit Inputs + +Components with built-in unit suffixes: + +- **CmInput**: centimeters (cm) +- **InchInput**: inches (in) +- **TimeInput**: seconds (s) + +Example usage: +```javascript +const [length, setLength] = useState(150); + +``` + +## Angular Measurement Inputs + +### DegInput and RadInput + +**DegInput** displays degrees (°), while **RadInput** offers flexible display formats: + +| Mode | Display | Example | +|------|---------|---------| +| `"rad"` | Radians | 1.57 rad | +| `"deg"` | Degrees | 90° | +| `"pi"` | π multiples | 0.5π | + +The underlying value remains in radians regardless of display format. + +```javascript +const [radians, setRadians] = useState(Math.PI / 2); + +``` + +### PresetsRadInput + +Combines **RadInput** with preset buttons for common angles: + +```javascript +const [angle, setAngle] = useState(0); +const commonAngles = [0, Math.PI/2, Math.PI]; + + +``` + +## Integer Input + +**IntInput** restricts values to integers only: + +```javascript +const [count, setCount] = useState(42); + +``` + +## Vector Inputs + +Multi-dimensional components for 3D data: + +- **Vec3Input**: x, y, z coordinates +- **EulerInput**: x°, y°, z° (degrees) +- **EulerRadInput**: x, y, z (radians with flexible display) +- **QuaternionInput**: w, x, y, z components + +```javascript +const [position, setPosition] = useState([1, 0, 0]); + + +const [rotationRad, setRotationRad] = useState([0, Math.PI/2, Math.PI]); + +``` + +### Euler Angle Components Comparison + +| Component | Storage | Display Options | +|-----------|---------|-----------------| +| `EulerInput` | Degrees | Always degrees | +| `EulerRadInput` | Radians | `"rad"`, `"deg"`, `"pi"` | + +## Drag Interaction Features + +All specialized inputs support advanced drag interactions inherited from InputNumbers: + +- **Vertical drag**: Select multiple inputs +- **Horizontal drag**: Modify selected values +- **Shift + drag**: 5× step multiplier +- **Alt + drag**: 0.2× step multiplier diff --git a/docs/guides/getting-started.md b/docs/guides/getting-started.md new file mode 100644 index 0000000..fece6e4 --- /dev/null +++ b/docs/guides/getting-started.md @@ -0,0 +1,46 @@ +# Vuer UIKit Getting Started Guide + +## Overview + +The VUER UI Kit is a React component library designed to integrate with VUER for controlling 3D scenes. This documentation provides guidance on setup and component usage. + +## Installation + +To begin using the toolkit, install the package via yarn: + +``` +yarn add @vuer-ai/vuer-uikit +``` + +## Quick Start Example + +Here's a basic implementation to verify successful setup: + +```jsx +import { Button } from '@vuer-ai/vuer-uikit'; + +function App() { + return ; +} +``` + +## Next Steps + +After installation, the documentation recommends exploring the Getting Started guide to learn project setup details and component implementation patterns. + +## Available Components + +The library includes over 40 components organized by category: + +- **Form Inputs**: Input fields, number inputs, specialized controls +- **Layout Components**: Modals, drawers, cards, sidebar, navbar +- **Interactive Elements**: Buttons, toggles, dropdowns, tabs, sliders +- **Display Components**: Avatars, badges, progress indicators, tooltips +- **Advanced Features**: Tree views, tables, pagination, drag-selectable elements + +## Additional Resources + +- Style guide covering colors, fonts, icons, and layout principles +- Dial system documentation for input type handling +- Menu and toolbar layout patterns +- Hook utilities for React integration diff --git a/docs/guides/introduction.md b/docs/guides/introduction.md new file mode 100644 index 0000000..50a5064 --- /dev/null +++ b/docs/guides/introduction.md @@ -0,0 +1,39 @@ +# Vuer UIKit Introduction + +## Overview + +The Vuer UI Kit represents a comprehensive component library designed specifically for React applications. It integrates seamlessly with VUER to provide developers with the capability to manage 3D scene interactions. + +## Quick Start Guide + +Getting up and running with Vuer UI Kit requires just a few straightforward steps: + +### Installation + +Begin by installing the package using your preferred package manager: + +``` +yarn add @vuer-ai/vuer-uikit +``` + +### Basic Usage + +Once installed, you can immediately start building components: + +```javascript +import { Button } from '@vuer-ai/vuer-uikit'; + +function App() { + return ; +} +``` + +## Next Steps + +The documentation provides a "Getting Started" guide for developers seeking deeper knowledge about project setup and component implementation. This foundational resource helps developers understand how to leverage the full capabilities of the library in their applications. + +## Package Information + +- **Version**: v0.0.117 +- **Related CLI Tool**: dial-cli v0.0.22 +- **Repository**: Available on GitHub for community contributions and issue tracking diff --git a/docs/menu-tool-layouts/dock-layout.md b/docs/menu-tool-layouts/dock-layout.md new file mode 100644 index 0000000..68307c2 --- /dev/null +++ b/docs/menu-tool-layouts/dock-layout.md @@ -0,0 +1,71 @@ +1. Home +2. Menu Tool Layouts +3. Dock Layout + +# Dock Layout + +A traditional docking layout system that provides fixed-positioned panels and floating controls, similar to IDE and professional software interfaces. + +## Overview + +The Dock Layout provides a desktop application-like interface layout system where left, right, and bottom panels are fixed and docked to the viewport edges, while the top area remains floating. This layout is particularly useful for applications that need fixed tool panels, status bars, and floating controls. + +## Usage Recommendations + +- Theme Compatibility: The dock-layout component is recommended for use with non-liquid themes only. It may not work optimally with liquid-based layouts. +- Component Styling: When passing components to the left, right, or bottom props, it's recommended to remove shadow styles from these components for better visual integration (e.g., use className="shadow-none"). + +## Basic Usage + +Add Group 1 Group 3 Object 1 Object 2 Object 7 Group 2 Group 4 Object 3 Object 4 Group 5 Object 5 Object 6 Main Content + +Scene Camera Render Connection + +Background Color + +Color + +# World Transform + +Position + +X Y Z Rotation + +X Y Z Scale + +V HemisphereLight-[light-default-hemi] + +skyColor + +# groundColor + +# Intensity + +V Show Helper + +Hide + +DirectionalLight-[light-default-direct] + +Color + +# Intensity + +V Show Helper + +Hide + +Gizmo + +Enable + +[0] 0 1 ✕ FPS mujoco Maxlen [0] 0 ```tsx +} + right={} + bottom={} + top={} +> + + +``` \ No newline at end of file diff --git a/docs/menu-tool-layouts/liquid-float-layout.md b/docs/menu-tool-layouts/liquid-float-layout.md new file mode 100644 index 0000000..82f1c5b --- /dev/null +++ b/docs/menu-tool-layouts/liquid-float-layout.md @@ -0,0 +1,66 @@ +1. Home +2. Menu Tool Layouts +3. Liquid Float Layout + +# Liquid Float Layout + +A flexible floating layout system that allows elements to flow and position themselves dynamically based on content and available space. + +## Overview + +The Liquid Float Layout provides a fluid positioning system where elements can float and reposition themselves naturally, similar to how liquid adapts to its container. This layout is particularly useful for tool panels, menus, and dynamic content that needs to adapt to varying screen sizes and content lengths. + +## Basic Usage + +Main Content + +[0] 0 1 ✕ FPS mujoco Maxlen [0] 0 Scene Camera Render Connection + +Background Color + +Color + +# World Transform + +Position + +X Y Z Rotation + +X Y Z Scale + +V HemisphereLight-[light-default-hemi] + +skyColor + +# groundColor + +# Intensity + +V Show Helper + +Hide + +DirectionalLight-[light-default-direct] + +Color + +# Intensity + +V Show Helper + +Hide + +Gizmo + +Enable + +Add Group 1 Group 3 Object 1 Object 2 Object 7 Group 2 Group 4 Object 3 Object 4 Group 5 Object 5 Object 6 ```tsx +} + right={} + top={} + bottom={} +> + + +``` \ No newline at end of file diff --git a/docs/menu-tool-layouts/toolbar.md b/docs/menu-tool-layouts/toolbar.md new file mode 100644 index 0000000..64e103e --- /dev/null +++ b/docs/menu-tool-layouts/toolbar.md @@ -0,0 +1,197 @@ +1. Home +2. Menu Tool Layouts +3. Toolbar + +# Toolbar + +Simple, composable toolbar components for organizing buttons and actions. + +## Complex Example + +Add ```jsx +const [selectedTool, setSelectedTool] = useState("select"); + + return ( + + + + + + + + + + Select tool + + + + + + + + Edit tool + + + + + + + Cut + + + + + + Hand tool + + + + + + Hash tool + + + + + + Type tool + + + + + + + + ) +``` + +## Examples + +Add ```jsx + + + + + + + + + + + +``` + +## Components + +- Toolbar - Main container with variant support (default | floating) +- ToolbarGroup - Groups related buttons with gap spacing +- Button - Button component with toolbar-specific styling +- ToolbarSeparator - Short rounded visual separator + +## Floating Variant + +Add ```jsx + + + + + + + + + + +``` + +## Sizes + +```jsx +{/* Small toolbar - compact padding */} + + + + + + + +{/* Medium toolbar - default */} + + + + + + + +{/* Large toolbar - spacious padding */} + + + + + + +``` + +## API Reference + +### Toolbar + +```tsx +interface ToolbarProps { + className?: string + children?: React.ReactNode + variant?: "default" | "floating" + size?: "sm" | "md" | "lg" +} +``` + +### Button + +```tsx +interface ButtonProps { + variant?: "primary" | "secondary" | "destructive" | "ghost" | "link" + size?: "sm" | "md" | "lg" + icon?: boolean + className?: string + children: React.ReactNode + onClick?: () => void + disabled?: boolean + tooltip?: string +} +``` \ No newline at end of file diff --git a/docs/other/hooks.md b/docs/other/hooks.md new file mode 100644 index 0000000..77cc916 --- /dev/null +++ b/docs/other/hooks.md @@ -0,0 +1,150 @@ +# Vuer UIKit Hooks Documentation + +## Overview + +Vuer UIKit provides a collection of React hooks designed to be SSR-safe and fully typed with TypeScript support. All hooks return `undefined` during server-side rendering and properly hydrate on the client side. + +## Available Hooks + +### useLocation + +Tracks the current browser location and automatically updates when navigation occurs. + +**Usage:** +```jsx +import { useLocation } from '@vuer-ai/vuer-uikit'; + +function MyComponent() { + const location = useLocation(); + + if (!location) { + return null; // Handle SSR or initial load + } + + return ( +
+

Current path: {location.pathname}

+

Query params: {location.search}

+

Hash: {location.hash}

+
+ ); +} +``` + +### useWindow + +Provides safe access to the window object in server-side rendering environments. + +**Usage:** +```jsx +import { useWindow } from '@vuer-ai/vuer-uikit'; + +function MyComponent() { + const window = useWindow(); + + useEffect(() => { + if (window) { + console.log('Window width:', window.innerWidth); + } + }, [window]); + + return
Component content
; +} +``` + +### useDocument + +Enables safe access to the document object in SSR environments. + +**Usage:** +```jsx +import { useDocument } from '@vuer-ai/vuer-uikit'; + +function MyComponent() { + const document = useDocument(); + + useEffect(() => { + if (document) { + const element = document.getElementById('my-element'); + } + }, [document]); + + return
Component content
; +} +``` + +### useLocalStorage + +Maintains a stateful value synchronized with browser local storage. + +**Usage:** +```jsx +import { useLocalStorage } from '@vuer-ai/vuer-uikit'; + +function MyComponent() { + const [theme, setTheme] = useLocalStorage('theme', 'light'); + + return ( + + ); +} +``` + +### useIsMobile + +Detects whether the current device is mobile based on viewport width. Useful for conditional rendering of mobile versus desktop layouts. + +**Usage:** +```jsx +import { useIsMobile } from '@vuer-ai/vuer-uikit'; + +function MyComponent() { + const isMobile = useIsMobile(); + + return ( +
+ {isMobile ? : } +
+ ); +} +``` + +### useDragSelect + +Enables drag selection functionality for selectable elements. + +**Usage:** +```jsx +import { useDragSelect } from '@vuer-ai/vuer-uikit'; + +function MyComponent() { + const { selectedKeys, setSelectedKeys } = useDragSelect(); + + return ( +
+ {items.map(item => ( +
+ {item.name} +
+ ))} +
+ ); +} +``` + +### useQueryParams + +Handles URL query parameter management and updates. + +## Key Features + +- **SSR-Safe**: All hooks safely handle server-side rendering environments +- **TypeScript Support**: Fully typed with automatic handling of optional values during SSR +- **No Errors**: Browser API hooks won't throw errors on the server +- **Client Hydration**: State properly syncs between server and client diff --git a/docs/save_files.sh b/docs/save_files.sh new file mode 100755 index 0000000..85d6387 --- /dev/null +++ b/docs/save_files.sh @@ -0,0 +1,4 @@ +#!/bin/bash + +# This script will be populated with file saves +echo "Saving Dial files..." diff --git a/docs/style-guide/colors.md b/docs/style-guide/colors.md new file mode 100644 index 0000000..eaa8c90 --- /dev/null +++ b/docs/style-guide/colors.md @@ -0,0 +1,92 @@ +# Color Guidelines + +This documentation outlines the color system utilized in the VUER UI Kit. + +## Brand Colors + +| Variable | Dark Mode | Light Mode | Liquid Dark | Liquid Light | +|----------|-----------|-----------|-------------|--------------| +| `--brand-primary` | rgba(0, 123, 255, 1) | rgba(0, 123, 255, 1) | rgba(0, 123, 255, 1) | rgba(0, 123, 255, 1) | +| `--brand-hover` | rgba(41, 151, 255, 1) | rgba(41, 151, 255, 1) | rgba(41, 151, 255, 1) | rgba(41, 151, 255, 1) | +| `--brand-pressed` | rgba(0, 74, 179, 1) | rgba(0, 74, 179, 1) | rgba(0, 74, 179, 1) | rgba(0, 74, 179, 1) | + +## Background Colors + +| Variable | Dark Mode | Light Mode | Liquid Dark | Liquid Light | +|----------|-----------|-----------|-------------|--------------| +| `--bg-primary` | rgba(29, 29, 30, 1) | rgba(255, 255, 255, 1) | rgba(29, 29, 30, 1) | rgba(255, 255, 255, 1) | +| `--bg-secondary` | rgba(90, 93, 98, 0.3) | rgba(227, 230, 235, 0.6) | rgba(90, 93, 98, 0.3) | rgba(227, 230, 235, 0.6) | +| `--bg-tertiary` | rgba(75, 77, 83, 1) | rgba(220, 222, 229, 1) | rgba(75, 77, 83, 1) | rgba(220, 222, 229, 1) | +| `--bg-quaternary` | rgba(87, 90, 96, 1) | rgba(202, 206, 217, 1) | rgba(87, 90, 96, 1) | rgba(202, 206, 217, 1) | +| `--bg-mask` | rgba(56, 57, 59, 0.5) | rgba(56, 57, 59, 0.5) | rgba(56, 57, 59, 0.5) | rgba(246, 247, 248, 0.8) | + +## Text Colors + +| Variable | Dark Mode | Light Mode | Liquid Dark | Liquid Light | +|----------|-----------|-----------|-------------|--------------| +| `--text-highlight` | rgba(255, 255, 255, 1) | rgba(0, 0, 0, 1) | rgba(255, 255, 255, 1) | rgba(0, 0, 0, 1) | +| `--text-primary` | rgba(220, 222, 229, 1) | rgba(52, 53, 56, 1) | rgba(220, 222, 229, 1) | rgba(52, 53, 56, 1) | +| `--text-secondary` | rgba(147, 150, 159, 1) | rgba(87, 90, 96, 1) | rgba(147, 150, 159, 1) | rgba(87, 90, 96, 1) | +| `--text-tertiary` | rgba(121, 124, 131, 1) | rgba(147, 150, 159, 1) | rgba(121, 124, 131, 1) | rgba(147, 150, 159, 1) | +| `--text-withbg` | rgba(255, 255, 255, 1) | rgba(255, 255, 255, 1) | rgba(255, 255, 255, 1) | rgba(255, 255, 255, 1) | + +## Icon Colors + +| Variable | Dark Mode | Light Mode | Liquid Dark | Liquid Light | +|----------|-----------|-----------|-------------|--------------| +| `--icon-highlight` | rgba(255, 255, 255, 1) | rgba(0, 0, 0, 1) | rgba(255, 255, 255, 1) | rgba(0, 0, 0, 1) | +| `--icon-primary` | rgba(220, 222, 229, 1) | rgba(75, 77, 83, 1) | rgba(220, 222, 229, 1) | rgba(75, 77, 83, 1) | +| `--icon-secondary` | rgba(147, 150, 159, 1) | rgba(121, 124, 131, 1) | rgba(147, 150, 159, 1) | rgba(121, 124, 131, 1) | +| `--icon-tertiary` | rgba(121, 124, 131, 1) | rgba(181, 184, 196, 1) | rgba(121, 124, 131, 1) | rgba(181, 184, 196, 1) | +| `--icon-withbg` | rgba(255, 255, 255, 1) | rgba(255, 255, 255, 1) | rgba(255, 255, 255, 1) | rgba(255, 255, 255, 1) | + +## Danger Colors + +| Variable | Dark Mode | Light Mode | Liquid Dark | Liquid Light | +|----------|-----------|-----------|-------------|--------------| +| `--danger-primary` | rgba(255, 69, 91, 1) | rgba(255, 69, 91, 1) | rgba(255, 69, 91, 1) | rgba(255, 69, 91, 1) | +| `--danger-secondary` | rgba(255, 150, 156, 1) | rgba(255, 150, 156, 1) | rgba(255, 150, 156, 1) | rgba(255, 150, 156, 1) | +| `--danger-tertiary` | rgba(179, 30, 58, 1) | rgba(179, 30, 58, 1) | rgba(179, 30, 58, 1) | rgba(179, 30, 58, 1) | + +## Accent Colors + +| Variable | Dark Mode | Light Mode | Liquid Dark | Liquid Light | +|----------|-----------|-----------|-------------|--------------| +| `--accent-warning` | rgba(251, 187, 49, 1) | rgba(251, 187, 49, 1) | rgba(251, 187, 49, 1) | rgba(251, 187, 49, 1) | +| `--accent-success` | rgba(84, 190, 125, 1) | rgba(84, 190, 125, 1) | rgba(84, 190, 125, 1) | rgba(84, 190, 125, 1) | + +## Line Colors + +| Variable | Dark Mode | Light Mode | Liquid Dark | Liquid Light | +|----------|-----------|-----------|-------------|--------------| +| `--line-primary` | rgba(75, 77, 83, 1) | rgba(220, 222, 229, 1) | rgba(75, 77, 83, 0.5) | rgba(173, 176, 183, 0.6) | +| `--line-secondary` | rgba(52, 53, 56, 1) | rgba(245, 245, 245, 1) | rgba(52, 53, 56, 1) | rgba(245, 245, 245, 1) | + +## Shadow Colors + +| Variable | Dark Mode | Light Mode | Liquid Dark | Liquid Light | +|----------|-----------|-----------|-------------|--------------| +| `--shadow-primary` | rgba(0, 0, 0, 0.6) | rgba(0, 0, 0, 0.1) | rgba(0, 0, 0, 0.6) | rgba(0, 0, 0, 0.1) | +| `--shadow-secondary` | rgba(0, 0, 0, 0.2) | rgba(0, 0, 0, 0.06) | rgba(0, 0, 0, 0.2) | rgba(0, 0, 0, 0.06) | + +## Alternative Colors + +| Variable | Dark Mode | Light Mode | Liquid Dark | Liquid Light | +|----------|-----------|-----------|-------------|--------------| +| `--alt-primary` | rgba(52, 53, 56, 1) | rgba(245, 245, 245, 1) | rgba(52, 53, 56, 1) | rgba(245, 245, 245, 1) | +| `--alt-hover` | rgba(87, 90, 96, 1) | rgba(220, 222, 229, 1) | rgba(87, 90, 96, 1) | rgba(220, 222, 229, 1) | +| `--alt-pressed` | rgba(75, 77, 83, 1) | rgba(245, 245, 245, 1) | rgba(75, 77, 83, 1) | rgba(245, 245, 245, 1) | + +## Group Colors + +| Variable | Dark Mode | Light Mode | Liquid Dark | Liquid Light | +|----------|-----------|-----------|-------------|--------------| +| `--group-primary` | rgba(0, 0, 0, 1) | rgba(255, 255, 255, 1) | rgba(255, 255, 255, 1) | rgba(255, 255, 255, 1) | +| `--group-hover` | rgba(52, 53, 56, 1) | rgba(245, 245, 245, 1) | rgba(52, 53, 56, 1) | rgba(245, 245, 245, 1) | +| `--group-pressed` | rgba(29, 29, 30, 1) | rgba(220, 222, 229, 1) | rgba(220, 222, 229, 1) | rgba(220, 222, 229, 1) | + +## Select Colors + +| Variable | Dark Mode | Light Mode | Liquid Dark | Liquid Light | +|----------|-----------|-----------|-------------|--------------| +| `--select-secondary` | rgba(56, 57, 59, 0.5) | rgba(227, 230, 235, 0.6) | rgba(56, 57, 59, 0.5) | rgba(227, 230, 235, 0.6) | diff --git a/docs/style-guide/font.md b/docs/style-guide/font.md new file mode 100644 index 0000000..1f5ce26 --- /dev/null +++ b/docs/style-guide/font.md @@ -0,0 +1,26 @@ +# Font Style Guide + +## Font Family + +The design system uses **Inter** as its typeface. This is a freely available font from Google Fonts optimized for on-screen readability. + +## Typography Scale + +The following table documents the complete font sizing system used throughout the Vuer UIKit: + +| Style Name | Size (px) | Line Height | Weight | +|---|---|---|---| +| text-uk-h1 | 30 | 36 | 400 | +| text-uk-h2 | 24 | 32 | 400 | +| text-uk-h3 | 20 | 28 | 400 | +| text-uk-lg | 16 | 24 | 400 | +| text-uk-md | 14 | 20 | 400 | +| text-uk-subtitle | 13 | 18 | 400 | +| text-uk-sm | 12 | 16 | 400 | +| text-uk-xs | 11 | 14 | 400 | +| text-uk-xxs | 10 | 12 | 400 | +| text-uk-hint | 10 | 12 | 400 | + +## Key Information + +All typography styles utilize the Inter typeface, with measurements specified in pixels. Font weights remain consistent at 400 (regular) across all size variants. Line heights are provided as both variable names and pixel values for implementation flexibility. diff --git a/docs/style-guide/icons.md b/docs/style-guide/icons.md new file mode 100644 index 0000000..9b982ad --- /dev/null +++ b/docs/style-guide/icons.md @@ -0,0 +1,70 @@ +# Icons Style Guide + +## Overview + +The VUER UI Kit utilizes Lucide icons as its foundational icon system, providing a "comprehensive collection of beautifully crafted, customizable icons that maintain consistency" across applications. + +## Icon Sizing Guidelines + +| Size | Use Case | Description | +|------|----------|-------------| +| 16px | Dense interfaces | Compact layout icons | +| 20px | Default UI | Standard element sizing | +| 24px | Buttons/Actions | Primary action buttons | +| 32px | Emphasis | Large touch target icons | + +## Color Application + +| Type | Usage | Application | +|------|-------|-------------| +| Current Color | Default | Inherits parent text color | +| Gray Scale | Secondary | Disabled states and subtle elements | +| Accent Colors | Emphasis | Actions and highlights (use sparingly) | + +## Implementation Guidelines + +**Best Practices:** +- Maintain consistent sizing within interface sections +- Scale proportionally when resizing +- Ensure minimum 44px touch targets for mobile devices + +### Stroke Width Options + +| Width | Usage | +|-------|-------| +| 1.5 | Default | +| 1 | Light | +| 2 | Bold | + +## Code Examples + +**Standard Usage:** +```javascript +import { ChevronUp, Plus, Search } from 'lucide-react'; + + +``` + +**Custom Styling:** +```javascript + +``` + +## Accessibility + +Always provide descriptive labels for icon-only buttons: +```javascript + +``` + +Hide purely decorative icons from screen readers using `aria-hidden="true"`. + +## Responsive Implementation + +Adjust sizes based on viewport dimensions for optimal display across devices. diff --git a/docs/style-guide/layout.md b/docs/style-guide/layout.md new file mode 100644 index 0000000..93b7d7d --- /dev/null +++ b/docs/style-guide/layout.md @@ -0,0 +1,30 @@ +# Layout Guidelines + +This section presents the design tokens used throughout the VUER UI Kit, focusing on spacing and border radius values. + +## Spacing Scale + +The spacing system uses a 4px base unit to ensure consistent spacing across the interface. + +| Variable | Value | +|----------|-------| +| `--spacing-xxs` | 2px | +| `--spacing-xs` | 4px | +| `--spacing-sm` | 6px | +| `--spacing-md` | 8px | +| `--spacing-lg` | 12px | +| `--spacing-xl` | 16px | + +## Border Radius Scale + +The border radius system provides standardized rounded corners for components throughout the design system. + +| Variable | Value | +|----------|-------| +| `--radius-uk-xs` | 4px | +| `--radius-uk-sm` | 6px | +| `--radius-uk-md` | 8px | +| `--radius-uk-lg` | 12px | +| `--radius-uk-xl` | 16px | + +These design tokens serve as foundational building blocks for creating visual consistency and maintaining rhythm within VUER UI Kit components. diff --git a/fetch_remaining.sh b/fetch_remaining.sh new file mode 100644 index 0000000..ad8a394 --- /dev/null +++ b/fetch_remaining.sh @@ -0,0 +1,91 @@ +#!/bin/bash + +# Script to fetch remaining Vuer UIKit documentation pages +# This script uses curl to fetch pages and saves them as markdown files + +BASE_URL="https://uikit.vuer.ai" +DOCS_DIR="/Users/ge/fortyfive/awesome-skills/skills/vuer-uikit/docs" + +# Function to fetch and save a page +fetch_page() { + local url="$1" + local output_file="$2" + local description="$3" + + echo "Fetching: $description" + echo " URL: $url" + echo " Output: $output_file" + + # Create directory if it doesn't exist + mkdir -p "$(dirname "$output_file")" + + # Fetch the page (you'll need to use WebFetch via Claude for actual content) + echo " Status: Ready to fetch" + echo "" +} + +echo "================================" +echo "Vuer UIKit Documentation Fetcher" +echo "================================" +echo "" + +# Remaining Components (35 total) +echo "COMPONENTS TO FETCH (35):" +echo "------------------------" + +components=( + "card" + "checkbox" + "collapsible" + "cursor-display" + "drag-selectable" + "drawer" + "dropdown" + "layout" + "modal" + "navbar" + "navigation" + "pagination" + "popover" + "preview" + "progress" + "radio-group" + "select" + "sheet" + "sidebar" + "simple-tree-view" + "slider" + "spinner" + "switch" + "sync-scroll" + "table" + "tabs" + "textarea" + "toast" + "toggle" + "toggle-buttons" + "toggle-group" + "tooltip" + "tree-view" + "version-badge" + "waterfall" +) + +for comp in "${components[@]}"; do + url="${BASE_URL}/components/${comp}/" + output="${DOCS_DIR}/components/${comp}.md" + fetch_page "$url" "$output" "Component: $comp" +done + +echo "================================" +echo "Summary:" +echo " Total components to fetch: ${#components[@]}" +echo "================================" +echo "" +echo "Note: This script lists the pages to fetch." +echo "Use Claude's WebFetch tool to actually retrieve the content." +echo "" +echo "Example Claude command for each:" +echo " WebFetch URL: ${BASE_URL}/components/card/" +echo " Prompt: Extract the main documentation content about the Card component..." +echo "" diff --git a/plugin.lock.json b/plugin.lock.json new file mode 100644 index 0000000..98d1820 --- /dev/null +++ b/plugin.lock.json @@ -0,0 +1,305 @@ +{ + "$schema": "internal://schemas/plugin.lock.v1.json", + "pluginId": "gh:vuer-ai/vuer-skill-marketplace:skills/vuer-uikit", + "normalized": { + "repo": null, + "ref": "refs/tags/v20251128.0", + "commit": "8441eb0263dad23d300dead342d6e7597a0255eb", + "treeHash": "ccd52143480a5fe9cbe76c3abd0becd5265e41b443f7d74c2be9ea97b562d0f3", + "generatedAt": "2025-11-28T10:28:56.900816Z", + "toolVersion": "publish_plugins.py@0.2.0" + }, + "origin": { + "remote": "git@github.com:zhongweili/42plugin-data.git", + "branch": "master", + "commit": "aa1497ed0949fd50e99e70d6324a29c5b34f9390", + "repoRoot": "/Users/zhongweili/projects/openmind/42plugin-data" + }, + "manifest": { + "name": "vuer-uikit", + "description": "Complete documentation for Vuer UIKit React component library including 38 UI components, Dial system for control panels, style guides, and layout patterns", + "version": "0.1.0" + }, + "content": { + "files": [ + { + "path": "fetch_remaining.sh", + "sha256": "6ab917fe5516f9e9de68d62fc3c48bd73c3aac15578afd5847f042bbd9f41d9d" + }, + { + "path": "COMPLETION_STATUS.md", + "sha256": "3c0dad0b20858880f2a5586c48ba7483d38a419ae32355f7bfe1817da35d37b2" + }, + { + "path": "README.md", + "sha256": "55b6434c981a4d715aa8499dc2fd0ee3ed2996a0b52b2067f5580fdbd1659452" + }, + { + "path": "SKILL.md", + "sha256": "d2999be6b2df77672e57184a173339161ec56376b0575507b05dd0c1ebf32eb9" + }, + { + "path": "docs/save_files.sh", + "sha256": "fa2cd36e5eea4fc97904a7d03ccaf4ee1f1cb465635407e31bb74f0e15e01832" + }, + { + "path": "docs/README.md", + "sha256": "6782bb460a3b1080184e8a29abff7ca0f51d7efea9ba461f83665513c09d252b" + }, + { + "path": "docs/other/hooks.md", + "sha256": "4201dc22aeacb1ab4747c15a23345b1a001992ebbb3e41eb51a336753785e2dd" + }, + { + "path": "docs/dial/controlled-dials.md", + "sha256": "a56faf52f3cda80fd2bfeb4b0d4eb6b3948e0350e6a3f16c7f78403420a733b3" + }, + { + "path": "docs/dial/overview.md", + "sha256": "62aad0eb362aef8e597888caedf0755e91266ee591231f937186b0b2d623ca00" + }, + { + "path": "docs/dial/api-notes.md", + "sha256": "f6c84dc41740014f6c1071e5c8fda72db8a7dad701367abcedd7d80df3ed4f3a" + }, + { + "path": "docs/dial/input-types.md", + "sha256": "fece7505d013297eb2d72429dac7378086332471d186dcbc5d5de587e321eaa6" + }, + { + "path": "docs/dial/testing.md", + "sha256": "86142edd371f15432880fc7c63e551d210ac713dcf594585520359efbed69d94" + }, + { + "path": "docs/dial/type-inheritance.md", + "sha256": "e90d551602033f641213391c878c1dc8a1a5137681276300a75e158c8875bc1a" + }, + { + "path": "docs/dial/getting-started.md", + "sha256": "fdefc04150e9f1a589ad2e42827859a6ae75970b06b452050c811ce75cd05383" + }, + { + "path": "docs/dial/tutorial.md", + "sha256": "f8f3e64b73ad0f51de476450b7ade646d3c97d207331b715976f22dfe17c8a79" + }, + { + "path": "docs/dial/cli-details.md", + "sha256": "db4ebe15caccfcef234b7ff81758c746664cd4cee63641cda19c08b33c6fe0e6" + }, + { + "path": "docs/components/radio-group.md", + "sha256": "dab29bed57a2456cad273adcdb9b9b1c02624bdbe46ea2f1295aa1a3cbe0b7ef" + }, + { + "path": "docs/components/modal.md", + "sha256": "4b726e6a8f29dbcbb5364527d50f0de9674509ad49014a721bcc7bd2c8ef1d5a" + }, + { + "path": "docs/components/toast.md", + "sha256": "a57d764cb4ec01b5296b77ae69f5227ad2758b9cb0baa4b2ead6268bcb67297e" + }, + { + "path": "docs/components/toggle-buttons.md", + "sha256": "11a026aedc2a8fd2458db81a4298a65f3e89bc8f40e3e718bd4ff08a1023f3bd" + }, + { + "path": "docs/components/simple-tree-view.md", + "sha256": "19be21d6a0bfabb73a9c194028df8aa36d5d626704d2eb115af8a222b4e33d37" + }, + { + "path": "docs/components/waterfall.md", + "sha256": "dd0033265db6917f1589c4949004f7ab58d0b31174edc652d7e90d097f75f207" + }, + { + "path": "docs/components/slider.md", + "sha256": "e15f8a312c0dd1d94d108eb8f9c98aebdda7817733d4b72f86960f89dcd3f713" + }, + { + "path": "docs/components/card.md", + "sha256": "f6d64af31ec7c7d53f4db9934039849b0d3c6a3e63ebdd70a0064f36c6b8e381" + }, + { + "path": "docs/components/sheet.md", + "sha256": "e82a1a80f1167b7660dabe5d80a5a5c40ac215ae12c9d733116236563fbd6613" + }, + { + "path": "docs/components/button.md", + "sha256": "309141bd8ad5e8f85bdf4a893e05243105b68f7e4497aac6c0ddfeab5d822998" + }, + { + "path": "docs/components/sync-scroll.md", + "sha256": "b65a14ad4dbb6e6eb29c9a70f52437689877ae6485dd0569e63918c551020a00" + }, + { + "path": "docs/components/checkbox.md", + "sha256": "33261e401950e845518fe7c1262f6ba7e51bb17084d60cf1d4b3d5214fc00e17" + }, + { + "path": "docs/components/popover.md", + "sha256": "7994fd8a219548b1ee3c2aa8a9887a48fbdd0626927eeb0cfa3e031201918e7c" + }, + { + "path": "docs/components/pagination.md", + "sha256": "e75e7e86280edd2bc77d6648242988d0b2c4cea7e3fb91ca4cf5114547075194" + }, + { + "path": "docs/components/progress.md", + "sha256": "c9137d75987e5b2285239b8c5cd37384ba8a992864f9dc548776049461522b70" + }, + { + "path": "docs/components/select.md", + "sha256": "6400112295217bcd91113e8e7a5a035eb5a692b9f537a5e7ffed1e6ac191e155" + }, + { + "path": "docs/components/navigation.md", + "sha256": "5b260578d35dcd48c23974438e026be8c6d0b7cf3ae81a9fcbd129d6c768abaf" + }, + { + "path": "docs/components/table.md", + "sha256": "a57d764cb4ec01b5296b77ae69f5227ad2758b9cb0baa4b2ead6268bcb67297e" + }, + { + "path": "docs/components/dropdown.md", + "sha256": "4ab367300852e698f81af20f00328309f1af1ff9c405e3b5bb4a0fe26c3a65be" + }, + { + "path": "docs/components/spinner.md", + "sha256": "15d6add1a8af71ab30b662303a04787043d9136aa8b947bf64e9bb6047f6f51d" + }, + { + "path": "docs/components/drag-selectable.md", + "sha256": "66ca74d4595ffe9b0d6c1c035ef6d70decabbb4e183f90ae72546e151a599e39" + }, + { + "path": "docs/components/cursor-display.md", + "sha256": "f382ddcd30c2c90b0cbfb932ed8572e68d2ce70d383753d50e259684cfc00eb0" + }, + { + "path": "docs/components/drawer.md", + "sha256": "dadd00508d7f26d2c1108e4fa21edea1acaac6ccb18e71d545b1b5dedcdda10c" + }, + { + "path": "docs/components/tabs.md", + "sha256": "a57d764cb4ec01b5296b77ae69f5227ad2758b9cb0baa4b2ead6268bcb67297e" + }, + { + "path": "docs/components/sidebar.md", + "sha256": "a2916de912b9afb33fd18649830dfd94885f6d0cf77705c272c7f2db9896b4eb" + }, + { + "path": "docs/components/preview.md", + "sha256": "b84d0149356a355ce037bdb22cb32d6904eeb401c863c38f68e0a52f153af4a4" + }, + { + "path": "docs/components/toggle.md", + "sha256": "a57d764cb4ec01b5296b77ae69f5227ad2758b9cb0baa4b2ead6268bcb67297e" + }, + { + "path": "docs/components/textarea.md", + "sha256": "a57d764cb4ec01b5296b77ae69f5227ad2758b9cb0baa4b2ead6268bcb67297e" + }, + { + "path": "docs/components/tree-view.md", + "sha256": "19be21d6a0bfabb73a9c194028df8aa36d5d626704d2eb115af8a222b4e33d37" + }, + { + "path": "docs/components/navbar.md", + "sha256": "75bb29e9bf7a1f46ebaecb73ee2e09c01fd1b5a5ff29e90b526aeaada541c4f8" + }, + { + "path": "docs/components/switch.md", + "sha256": "315cf2c73a3645dbeccc73cfc58da57a97b7d0bedbb9afa498f685f8bb0c9dcd" + }, + { + "path": "docs/components/avatar.md", + "sha256": "7a1760174301fdd4ac0c16a40b26d09087e232660b2c30dbbd568e62c524804d" + }, + { + "path": "docs/components/toggle-group.md", + "sha256": "ef307ed02b8ce845fc83e15e5a8fc29cf436dfcb45df2ec7085e191d77344e3a" + }, + { + "path": "docs/components/tooltip.md", + "sha256": "e5394c9c1b92e88db6bf1b9b08ec0d4be53def002b04fea30ea9d6249e25e3ad" + }, + { + "path": "docs/components/badge.md", + "sha256": "02ae7ca1770bd975ceb0490c261df817ada9e3f2976e2a100f7cfc26cb03d5e8" + }, + { + "path": "docs/components/version-badge.md", + "sha256": "fe9aae0638016b40900f1b6a9cdd960e450559e1454dfff1907ddef7b01aff4e" + }, + { + "path": "docs/components/collapsible.md", + "sha256": "0551820914c7cb53d489e1970db94f90e94e56cb96d3da2a846521f3e8435f3a" + }, + { + "path": "docs/components/layout.md", + "sha256": "d8fdecf5896caa44c7f29742362d0b33e46fe117529908cc87e021d13aea09b8" + }, + { + "path": "docs/guides/introduction.md", + "sha256": "73ad6caa2d7648669b361d05e847c65214a5f815a64cc3fe6502aad389ef0565" + }, + { + "path": "docs/guides/getting-started.md", + "sha256": "6322473a1b0b091b28a99b430673646cb6314fa6f4e4f5c822e19df74ab617e3" + }, + { + "path": "docs/menu-tool-layouts/dock-layout.md", + "sha256": "8a429c7047b728521361faf35d7ee4426589517f4579d79cfccfcf485b005cc2" + }, + { + "path": "docs/menu-tool-layouts/toolbar.md", + "sha256": "6e7882dd450e4159dae2965be581184b2f93ec800d9f01772daebb9b827c805d" + }, + { + "path": "docs/menu-tool-layouts/liquid-float-layout.md", + "sha256": "ba4a5c7a608cafef0fb1b0ab2ff07a9c44b7add645ae19752e958298a6dbf9a6" + }, + { + "path": "docs/form-inputs/input.md", + "sha256": "ccb1a1c8d6f3e2f24febd2cfa7c3ac198f9ee04bb87981eee24b34f0c92d70c2" + }, + { + "path": "docs/form-inputs/playground.md", + "sha256": "8e5b8ebd88d7ff2e714ecc07a96525fb9339f969ad8e8687559b397c2ab022cd" + }, + { + "path": "docs/form-inputs/number-inputs.md", + "sha256": "1abae995121642045e3412fc8822d03aa9c3caae7dab4b753c42fb3ef9e2aedd" + }, + { + "path": "docs/form-inputs/specialized-inputs.md", + "sha256": "22252deffba69c005e5af62d4f6d9f4803ef92779d7406a14a13bbe920343c94" + }, + { + "path": "docs/style-guide/colors.md", + "sha256": "3eeb878b85f868887afc0f4c2ceafcf7b283b41bf6adc7e75a416055594e9d52" + }, + { + "path": "docs/style-guide/font.md", + "sha256": "1c56a26075d520aa32ef588dd2cec740374c2b4bdc43bc00802707e2983fad7f" + }, + { + "path": "docs/style-guide/icons.md", + "sha256": "060449051e1536b98bedc0b5200d50afd552fb512604bcc042d0027cff667425" + }, + { + "path": "docs/style-guide/layout.md", + "sha256": "083bdf38669df685f5a74487d20b8d996805c944448c6b8a1fdc78eb4ffd0c56" + }, + { + "path": ".claude-plugin/plugin.json", + "sha256": "a94567e37b7c8581171eba40c34489854d58b171170f561e53b866369abdc472" + } + ], + "dirSha256": "ccd52143480a5fe9cbe76c3abd0becd5265e41b443f7d74c2be9ea97b562d0f3" + }, + "security": { + "scannedAt": null, + "scannerVersion": null, + "flags": [] + } +} \ No newline at end of file