Skip to main content
Glama
ui-components.ts10.8 kB
/** * Component Contracts: Base UI Components * * TypeScript interfaces for shadcn/ui base components. * These contracts define the props for reusable UI components. * * Note: These are design-time contracts for planning. Actual implementations * will be generated by shadcn/ui CLI and may have additional props. */ import { ReactNode } from 'react' // ============================================================================ // Button Component // ============================================================================ export interface ButtonProps { /** * Visual style variant * @default 'default' */ variant?: 'default' | 'primary' | 'secondary' | 'ghost' | 'link' | 'destructive' /** * Size variant * @default 'md' */ size?: 'sm' | 'md' | 'lg' /** * Disabled state - prevents interaction * @default false */ disabled?: boolean /** * Loading state - shows spinner, disables interaction * @default false */ loading?: boolean /** * Click handler */ onClick?: () => void /** * Button type attribute * @default 'button' */ type?: 'button' | 'submit' | 'reset' /** * Button content */ children: ReactNode /** * Additional CSS classes */ className?: string } // ============================================================================ // Card Component // ============================================================================ export interface CardProps { children: ReactNode className?: string /** * Padding size * @default 'md' */ padding?: 'sm' | 'md' | 'lg' } export interface CardHeaderProps { children: ReactNode className?: string } export interface CardTitleProps { children: ReactNode className?: string } export interface CardDescriptionProps { children: ReactNode className?: string } export interface CardContentProps { children: ReactNode className?: string } export interface CardFooterProps { children: ReactNode className?: string } // ============================================================================ // Input Component // ============================================================================ export interface InputProps { /** * Input type * @default 'text' */ type?: 'text' | 'email' | 'password' | 'number' | 'tel' | 'url' /** * Placeholder text */ placeholder?: string /** * Current value */ value?: string /** * Change handler */ onChange?: (e: React.ChangeEvent<HTMLInputElement>) => void /** * Disabled state * @default false */ disabled?: boolean /** * Error state - shows red border * @default false */ error?: boolean /** * Error message to display below input */ errorMessage?: string /** * Label text */ label?: string /** * Required field indicator * @default false */ required?: boolean /** * Additional CSS classes */ className?: string } // ============================================================================ // Table Component // ============================================================================ export interface TableColumn<T> { /** * Data key to display in this column */ key: keyof T /** * Column header text */ header: string /** * Custom render function for cell content */ render?: (value: T[keyof T], row: T) => ReactNode /** * Whether this column is sortable * @default false */ sortable?: boolean /** * Column width (CSS value) */ width?: string } export interface TableProps<T> { /** * Array of data rows */ data: T[] /** * Column definitions */ columns: TableColumn<T>[] /** * Loading state - shows skeleton rows * @default false */ loading?: boolean /** * Message to display when data is empty * @default 'No data available' */ emptyMessage?: string /** * Row click handler */ onRowClick?: (row: T) => void /** * Current sort column key */ sortBy?: keyof T /** * Current sort direction */ sortDirection?: 'asc' | 'desc' /** * Sort change handler */ onSort?: (key: keyof T, direction: 'asc' | 'desc') => void } // ============================================================================ // Dialog (Modal) Component // ============================================================================ export interface DialogProps { /** * Whether the dialog is open */ open: boolean /** * Open state change handler */ onOpenChange: (open: boolean) => void /** * Dialog content */ children: ReactNode } export interface DialogContentProps { children: ReactNode className?: string } export interface DialogHeaderProps { children: ReactNode className?: string } export interface DialogTitleProps { children: ReactNode className?: string } export interface DialogDescriptionProps { children: ReactNode className?: string } export interface DialogFooterProps { children: ReactNode className?: string } // ============================================================================ // Skeleton Component // ============================================================================ export interface SkeletonProps { /** * Additional CSS classes */ className?: string /** * Width (CSS value) */ width?: string /** * Height (CSS value) */ height?: string /** * Skeleton variant * @default 'rectangular' */ variant?: 'text' | 'circular' | 'rectangular' } // ============================================================================ // Alert Component // ============================================================================ export interface AlertProps { /** * Alert visual variant * @default 'default' */ variant?: 'default' | 'info' | 'warning' | 'error' | 'success' /** * Alert title */ title?: string /** * Alert description */ description?: string /** * Whether the alert can be dismissed * @default false */ dismissible?: boolean /** * Dismiss handler */ onDismiss?: () => void /** * Alert content (alternative to title/description) */ children?: ReactNode /** * Additional CSS classes */ className?: string } // ============================================================================ // Badge Component // ============================================================================ export interface BadgeProps { /** * Badge visual variant * @default 'default' */ variant?: 'default' | 'primary' | 'secondary' | 'success' | 'warning' | 'error' /** * Badge content */ children: ReactNode /** * Additional CSS classes */ className?: string } // ============================================================================ // Select Component // ============================================================================ export interface SelectOption { value: string label: string } export interface SelectProps { /** * Available options */ options: SelectOption[] /** * Current selected value */ value?: string /** * Change handler */ onChange?: (value: string) => void /** * Placeholder text */ placeholder?: string /** * Disabled state * @default false */ disabled?: boolean /** * Error state * @default false */ error?: boolean /** * Label text */ label?: string /** * Required field indicator * @default false */ required?: boolean /** * Additional CSS classes */ className?: string } // ============================================================================ // Tooltip Component // ============================================================================ export interface TooltipProps { /** * Tooltip content */ content: string | ReactNode /** * Element to show tooltip on hover */ children: ReactNode /** * Tooltip position * @default 'top' */ side?: 'top' | 'right' | 'bottom' | 'left' /** * Delay before showing tooltip (milliseconds) * @default 200 */ delay?: number } // ============================================================================ // Form Component (Composition) // ============================================================================ export interface FormProps { /** * Form submit handler */ onSubmit: (data: any) => void | Promise<void> /** * Form content (Input, Select, Button components) */ children: ReactNode /** * Additional CSS classes */ className?: string } export interface FormFieldProps { /** * Field name (for form state) */ name: string /** * Field label */ label: string /** * Whether field is required * @default false */ required?: boolean /** * Field content (Input, Select, etc.) */ children: ReactNode /** * Error message */ error?: string /** * Helper text */ helperText?: string } // ============================================================================ // Usage Examples // ============================================================================ /** * Example: Button usage * * ```tsx * <Button variant="primary" size="lg" onClick={handleSubmit}> * Submit * </Button> * * <Button variant="destructive" disabled> * Delete * </Button> * ``` */ /** * Example: Card usage * * ```tsx * <Card> * <CardHeader> * <CardTitle>API Usage</CardTitle> * <CardDescription>Current month's metrics</CardDescription> * </CardHeader> * <CardContent> * <p>1,234 requests</p> * </CardContent> * <CardFooter> * <Button variant="link">View Details</Button> * </CardFooter> * </Card> * ``` */ /** * Example: Table usage * * ```tsx * <Table * data={apiKeys} * columns={[ * { key: 'name', header: 'Name', sortable: true }, * { key: 'createdAt', header: 'Created', render: (val) => formatDate(val) }, * ]} * sortBy="createdAt" * sortDirection="desc" * onRowClick={(row) => console.log(row)} * /> * ``` */ /** * Example: Dialog usage * * ```tsx * <Dialog open={isOpen} onOpenChange={setIsOpen}> * <DialogContent> * <DialogHeader> * <DialogTitle>Confirm Deletion</DialogTitle> * <DialogDescription> * Are you sure you want to delete this API key? * </DialogDescription> * </DialogHeader> * <DialogFooter> * <Button variant="secondary" onClick={() => setIsOpen(false)}> * Cancel * </Button> * <Button variant="destructive" onClick={handleDelete}> * Delete * </Button> * </DialogFooter> * </DialogContent> * </Dialog> * ``` */

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/darrentmorgan/hostaway-mcp'

If you have feedback or need assistance with the MCP directory API, please join our Discord server