@shalomormsby/ui 0.0.5

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/lib/animations.ts","../src/lib/breadcrumbs.ts","../src/lib/colors.ts","../src/lib/utils.ts","../src/lib/validation.ts","../src/lib/syntax-parser/patterns.ts","../src/lib/syntax-parser/tokenizer.ts","../src/lib/syntax-parser/index.ts"],"sourcesContent":["/**\n * Animation Presets\n *\n * Reusable animation configurations for consistent motion throughout the design system.\n * Works with Framer Motion and respects user motion preferences.\n */\n\n// Type definitions (compatible with Framer Motion)\nexport type Variant = {\n [key: string]: any;\n};\n\nexport type Variants = {\n [key: string]: Variant;\n};\n\nexport type Transition = {\n duration?: number;\n ease?: readonly number[] | number[] | string;\n type?: 'spring' | 'tween' | 'inertia';\n damping?: number;\n stiffness?: number;\n [key: string]: any;\n};\n\n/**\n * Animation Duration Presets\n * Based on Material Design motion guidelines\n */\nexport const durations = {\n instant: 0,\n fast: 0.15,\n normal: 0.3,\n slow: 0.5,\n slower: 0.7,\n} as const;\n\n/**\n * Easing Presets\n * Common easing curves for smooth animations\n */\nexport const easings = {\n // Standard easing - default for most transitions\n standard: [0.4, 0.0, 0.2, 1],\n\n // Deceleration - use when objects enter screen\n decelerate: [0.0, 0.0, 0.2, 1],\n\n // Acceleration - use when objects exit screen\n accelerate: [0.4, 0.0, 1, 1],\n\n // Sharp - use for very quick transitions\n sharp: [0.4, 0.0, 0.6, 1],\n\n // Bounce - playful animation\n bounce: [0.68, -0.55, 0.265, 1.55],\n} as const;\n\n/**\n * Common transition presets\n */\nexport const transitions = {\n default: {\n duration: durations.normal,\n ease: easings.standard,\n } as Transition,\n\n fast: {\n duration: durations.fast,\n ease: easings.standard,\n } as Transition,\n\n slow: {\n duration: durations.slow,\n ease: easings.standard,\n } as Transition,\n\n bounce: {\n duration: durations.normal,\n ease: easings.bounce,\n } as Transition,\n\n spring: {\n type: 'spring' as const,\n damping: 20,\n stiffness: 300,\n } as Transition,\n\n springBouncy: {\n type: 'spring' as const,\n damping: 10,\n stiffness: 100,\n } as Transition,\n} as const;\n\n/**\n * Fade Animation Variants\n */\nexport const fadeVariants: Variants = {\n hidden: { opacity: 0 },\n visible: { opacity: 1 },\n exit: { opacity: 0 },\n};\n\n/**\n * Slide Animation Variants\n */\nexport const slideVariants = {\n fromLeft: {\n hidden: { x: -20, opacity: 0 },\n visible: { x: 0, opacity: 1 },\n exit: { x: -20, opacity: 0 },\n },\n fromRight: {\n hidden: { x: 20, opacity: 0 },\n visible: { x: 0, opacity: 1 },\n exit: { x: 20, opacity: 0 },\n },\n fromTop: {\n hidden: { y: -20, opacity: 0 },\n visible: { y: 0, opacity: 1 },\n exit: { y: -20, opacity: 0 },\n },\n fromBottom: {\n hidden: { y: 20, opacity: 0 },\n visible: { y: 0, opacity: 1 },\n exit: { y: 20, opacity: 0 },\n },\n} as const;\n\n/**\n * Scale Animation Variants\n */\nexport const scaleVariants = {\n default: {\n hidden: { scale: 0.95, opacity: 0 },\n visible: { scale: 1, opacity: 1 },\n exit: { scale: 0.95, opacity: 0 },\n },\n grow: {\n hidden: { scale: 0.8, opacity: 0 },\n visible: { scale: 1, opacity: 1 },\n exit: { scale: 0.8, opacity: 0 },\n },\n pop: {\n hidden: { scale: 0 },\n visible: { scale: 1 },\n exit: { scale: 0 },\n },\n} as const;\n\n/**\n * Rotate Animation Variants\n */\nexport const rotateVariants = {\n default: {\n hidden: { rotate: -10, opacity: 0 },\n visible: { rotate: 0, opacity: 1 },\n exit: { rotate: 10, opacity: 0 },\n },\n flip: {\n hidden: { rotateX: 90, opacity: 0 },\n visible: { rotateX: 0, opacity: 1 },\n exit: { rotateX: -90, opacity: 0 },\n },\n} as const;\n\n/**\n * List/Stagger Animation Variants\n */\nexport const listVariants = {\n container: {\n hidden: { opacity: 0 },\n visible: {\n opacity: 1,\n transition: {\n staggerChildren: 0.1,\n },\n },\n },\n item: {\n hidden: { y: 20, opacity: 0 },\n visible: {\n y: 0,\n opacity: 1,\n },\n },\n} as const;\n\n/**\n * Modal/Overlay Animation Variants\n */\nexport const modalVariants = {\n overlay: {\n hidden: { opacity: 0 },\n visible: { opacity: 1 },\n exit: { opacity: 0 },\n },\n content: {\n hidden: { scale: 0.95, opacity: 0, y: 20 },\n visible: { scale: 1, opacity: 1, y: 0 },\n exit: { scale: 0.95, opacity: 0, y: 20 },\n },\n} as const;\n\n/**\n * Drawer/Sheet Animation Variants\n */\nexport const drawerVariants = {\n fromLeft: {\n hidden: { x: '-100%' },\n visible: { x: 0 },\n exit: { x: '-100%' },\n },\n fromRight: {\n hidden: { x: '100%' },\n visible: { x: 0 },\n exit: { x: '100%' },\n },\n fromTop: {\n hidden: { y: '-100%' },\n visible: { y: 0 },\n exit: { y: '-100%' },\n },\n fromBottom: {\n hidden: { y: '100%' },\n visible: { y: 0 },\n exit: { y: '100%' },\n },\n} as const;\n\n/**\n * Collapse/Expand Animation Variants\n */\nexport const collapseVariants = {\n collapsed: {\n height: 0,\n opacity: 0,\n transition: { duration: durations.fast },\n },\n expanded: {\n height: 'auto',\n opacity: 1,\n transition: { duration: durations.normal },\n },\n} as const;\n\n/**\n * Preset Animations\n * Complete animation configurations ready to use\n */\nexport const presets = {\n /**\n * Fade in/out animation\n */\n fade: {\n initial: 'hidden',\n animate: 'visible',\n exit: 'exit',\n variants: fadeVariants,\n transition: transitions.default,\n },\n\n /**\n * Slide from bottom animation\n */\n slideUp: {\n initial: 'hidden',\n animate: 'visible',\n exit: 'exit',\n variants: slideVariants.fromBottom,\n transition: transitions.default,\n },\n\n /**\n * Scale animation\n */\n scale: {\n initial: 'hidden',\n animate: 'visible',\n exit: 'exit',\n variants: scaleVariants.default,\n transition: transitions.default,\n },\n\n /**\n * Modal animation (overlay + content)\n */\n modal: {\n overlay: {\n initial: 'hidden',\n animate: 'visible',\n exit: 'exit',\n variants: modalVariants.overlay,\n transition: transitions.fast,\n },\n content: {\n initial: 'hidden',\n animate: 'visible',\n exit: 'exit',\n variants: modalVariants.content,\n transition: transitions.default,\n },\n },\n\n /**\n * List stagger animation\n */\n list: {\n container: {\n initial: 'hidden',\n animate: 'visible',\n variants: listVariants.container,\n },\n item: {\n variants: listVariants.item,\n },\n },\n} as const;\n\n/**\n * Helper to create a custom animation preset\n *\n * @example\n * ```tsx\n * const customFade = createAnimation({\n * hidden: { opacity: 0, scale: 0.8 },\n * visible: { opacity: 1, scale: 1 },\n * }, transitions.bounce);\n * ```\n */\nexport function createAnimation(\n variants: Variants,\n transition: Transition = transitions.default\n) {\n return {\n initial: 'hidden',\n animate: 'visible',\n exit: 'exit',\n variants,\n transition,\n };\n}\n\n/**\n * Helper to scale transition duration based on motion preference\n *\n * @example\n * ```tsx\n * const { scale } = useMotionPreference();\n * const duration = scaleDuration(durations.normal, scale);\n * ```\n */\nexport function scaleDuration(duration: number, scale: number): number {\n return duration * (scale / 10);\n}\n","import type { BreadcrumbItemLegacy } from '../components/navigation/Breadcrumbs';\n\nexport interface RouteConfig {\n [key: string]: {\n label: string;\n children?: RouteConfig;\n };\n}\n\n/**\n * Generates breadcrumb items from hash-based routing\n *\n * @param hash - Current window.location.hash (e.g., '#atoms/button')\n * @param routeConfig - Configuration mapping routes to labels\n * @param baseUrl - Base URL for href generation (default: '#')\n * @returns Array of breadcrumb items with the last item having no href\n *\n * @example\n * ```ts\n * const routeConfig = {\n * atoms: {\n * label: 'Components',\n * children: {\n * button: { label: 'Button' }\n * }\n * }\n * };\n *\n * // With hash: '#atoms/button'\n * const breadcrumbs = generateBreadcrumbs('#atoms/button', routeConfig);\n * // Returns: [\n * // { label: 'Home', href: '#' },\n * // { label: 'Components', href: '#atoms' },\n * // { label: 'Button' } // No href for current page\n * // ]\n * ```\n */\nexport function generateBreadcrumbs(\n hash: string,\n routeConfig: RouteConfig,\n baseUrl: string = '#'\n): BreadcrumbItemLegacy[] {\n // Remove '#' prefix and clean up\n const cleanHash = hash.replace(/^#/, '').trim();\n\n // If no hash, return just home\n if (!cleanHash) {\n return [{ label: 'Home', href: baseUrl }];\n }\n\n // Split path into segments\n const segments = cleanHash.split('/').filter(Boolean);\n const breadcrumbs: BreadcrumbItemLegacy[] = [{ label: 'Home', href: baseUrl }];\n\n let currentPath = '';\n let currentConfig = routeConfig;\n\n for (let i = 0; i < segments.length; i++) {\n const segment = segments[i];\n const isLast = i === segments.length - 1;\n\n currentPath += (currentPath ? '/' : '') + segment;\n\n // Look up label in config\n const config = currentConfig[segment];\n\n if (!config) {\n // Fallback: convert kebab-case to Title Case\n const label = segment\n .split('-')\n .map(word => word.charAt(0).toUpperCase() + word.slice(1))\n .join(' ');\n\n breadcrumbs.push({\n label,\n // No href for the last item (current page)\n href: isLast ? undefined : `${baseUrl}${currentPath}`,\n });\n } else {\n breadcrumbs.push({\n label: config.label,\n // No href for the last item (current page)\n href: isLast ? undefined : `${baseUrl}${currentPath}`,\n });\n\n // Update config for next level of nesting\n if (config.children) {\n currentConfig = config.children;\n }\n }\n }\n\n return breadcrumbs;\n}\n","/**\n * Semantic Color Utilities\n *\n * Helper functions for working with the design system's color tokens\n * and CSS variables.\n */\n\n/**\n * Color token categories\n */\nexport const colorTokens = {\n // Background colors\n background: 'var(--color-background)',\n backgroundSecondary: 'var(--color-background-secondary)',\n backgroundTertiary: 'var(--color-background-tertiary)',\n surface: 'var(--color-surface)',\n\n // Foreground/Text colors\n foreground: 'var(--color-foreground)',\n foregroundSecondary: 'var(--color-foreground-secondary)',\n foregroundTertiary: 'var(--color-foreground-tertiary)',\n textPrimary: 'var(--color-text-primary)',\n textSecondary: 'var(--color-text-secondary)',\n textMuted: 'var(--color-text-muted)',\n\n // Brand colors\n primary: 'var(--color-primary)',\n primaryForeground: 'var(--color-primary-foreground)',\n secondary: 'var(--color-secondary)',\n secondaryForeground: 'var(--color-secondary-foreground)',\n accent: 'var(--color-accent)',\n accentForeground: 'var(--color-accent-foreground)',\n\n // Semantic colors\n success: 'var(--color-success)',\n successForeground: 'var(--color-success-foreground)',\n warning: 'var(--color-warning)',\n warningForeground: 'var(--color-warning-foreground)',\n error: 'var(--color-error)',\n errorForeground: 'var(--color-error-foreground)',\n info: 'var(--color-info)',\n infoForeground: 'var(--color-info-foreground)',\n\n // Borders\n border: 'var(--color-border)',\n borderSubtle: 'var(--color-border-subtle)',\n\n // Interactive states\n hover: 'var(--color-hover)',\n active: 'var(--color-active)',\n focus: 'var(--color-focus)',\n\n // Links\n link: 'var(--color-link)',\n linkHover: 'var(--color-link-hover)',\n linkHoverForeground: 'var(--color-link-hover-foreground)',\n} as const;\n\n/**\n * Get CSS variable value from computed styles\n *\n * @param variableName - CSS variable name (with or without --)\n * @param element - Element to get computed style from (defaults to document.documentElement)\n * @returns The computed value of the CSS variable\n *\n * @example\n * ```ts\n * const primaryColor = getCSSVariable('--color-primary');\n * // Returns: '#0066ff' (or whatever the current theme's primary color is)\n * ```\n */\nexport function getCSSVariable(\n variableName: string,\n element: HTMLElement = document.documentElement\n): string {\n const name = variableName.startsWith('--') ? variableName : `--${variableName}`;\n return getComputedStyle(element).getPropertyValue(name).trim();\n}\n\n/**\n * Set CSS variable value\n *\n * @param variableName - CSS variable name (with or without --)\n * @param value - Value to set\n * @param element - Element to set the variable on (defaults to document.documentElement)\n *\n * @example\n * ```ts\n * setCSSVariable('--color-primary', '#ff0000');\n * ```\n */\nexport function setCSSVariable(\n variableName: string,\n value: string,\n element: HTMLElement = document.documentElement\n): void {\n const name = variableName.startsWith('--') ? variableName : `--${variableName}`;\n element.style.setProperty(name, value);\n}\n\n/**\n * Get contrasting foreground color for a background color\n *\n * @param backgroundToken - Background color token name (without 'var()')\n * @returns The appropriate foreground color token\n *\n * @example\n * ```ts\n * const foreground = getForegroundColor('--color-primary');\n * // Returns: 'var(--color-primary-foreground)'\n * ```\n */\nexport function getForegroundColor(backgroundToken: string): string {\n // Remove var() wrapper if present\n const token = backgroundToken.replace(/var\\(|\\)/g, '');\n\n // Map background tokens to their foreground pairs\n const foregroundMap: Record<string, string> = {\n '--color-primary': 'var(--color-primary-foreground)',\n '--color-secondary': 'var(--color-secondary-foreground)',\n '--color-accent': 'var(--color-accent-foreground)',\n '--color-success': 'var(--color-success-foreground)',\n '--color-warning': 'var(--color-warning-foreground)',\n '--color-error': 'var(--color-error-foreground)',\n '--color-info': 'var(--color-info-foreground)',\n '--color-background': 'var(--color-foreground)',\n '--color-surface': 'var(--color-text-primary)',\n };\n\n return foregroundMap[token] || 'var(--color-text-primary)';\n}\n\n/**\n * Semantic color groups for different use cases\n */\nexport const semanticColors = {\n /**\n * Status colors for indicating states\n */\n status: {\n success: {\n bg: colorTokens.success,\n fg: colorTokens.successForeground,\n },\n warning: {\n bg: colorTokens.warning,\n fg: colorTokens.warningForeground,\n },\n error: {\n bg: colorTokens.error,\n fg: colorTokens.errorForeground,\n },\n info: {\n bg: colorTokens.info,\n fg: colorTokens.infoForeground,\n },\n },\n\n /**\n * Brand colors for primary UI elements\n */\n brand: {\n primary: {\n bg: colorTokens.primary,\n fg: colorTokens.primaryForeground,\n },\n secondary: {\n bg: colorTokens.secondary,\n fg: colorTokens.secondaryForeground,\n },\n accent: {\n bg: colorTokens.accent,\n fg: colorTokens.accentForeground,\n },\n },\n\n /**\n * Interactive state colors\n */\n interactive: {\n default: {\n bg: colorTokens.background,\n fg: colorTokens.foreground,\n },\n hover: {\n bg: colorTokens.hover,\n fg: colorTokens.foreground,\n },\n active: {\n bg: colorTokens.active,\n fg: colorTokens.foreground,\n },\n focus: {\n border: colorTokens.focus,\n },\n },\n} as const;\n\n/**\n * Helper to create color pairs (background + foreground)\n *\n * @param type - Semantic color type\n * @returns Object with bg and fg (and optionally border)\n *\n * @example\n * ```tsx\n * const errorColors = getSemanticColorPair('error');\n * <div style={{\n * backgroundColor: errorColors.bg,\n * color: errorColors.fg\n * }}>\n * Error message\n * </div>\n * ```\n */\nexport function getSemanticColorPair(\n type: 'success' | 'warning' | 'error' | 'info' | 'primary' | 'secondary' | 'accent'\n): { bg: string; fg: string } {\n if (type === 'primary' || type === 'secondary' || type === 'accent') {\n return semanticColors.brand[type];\n }\n return semanticColors.status[type];\n}\n\n/**\n * Convert hex color to RGB values\n *\n * @param hex - Hex color string (with or without #)\n * @returns Object with r, g, b values (0-255)\n *\n * @example\n * ```ts\n * const rgb = hexToRgb('#0066ff');\n * // Returns: { r: 0, g: 102, b: 255 }\n * ```\n */\nexport function hexToRgb(hex: string): { r: number; g: number; b: number } | null {\n const result = /^#?([a-f\\d]{2})([a-f\\d]{2})([a-f\\d]{2})$/i.exec(hex);\n return result\n ? {\n r: parseInt(result[1], 16),\n g: parseInt(result[2], 16),\n b: parseInt(result[3], 16),\n }\n : null;\n}\n\n/**\n * Calculate relative luminance of a color (WCAG formula)\n *\n * @param r - Red value (0-255)\n * @param g - Green value (0-255)\n * @param b - Blue value (0-255)\n * @returns Relative luminance (0-1)\n */\nexport function getLuminance(r: number, g: number, b: number): number {\n const [rs, gs, bs] = [r, g, b].map((c) => {\n const srgb = c / 255;\n return srgb <= 0.03928 ? srgb / 12.92 : Math.pow((srgb + 0.055) / 1.055, 2.4);\n });\n return 0.2126 * rs + 0.7152 * gs + 0.0722 * bs;\n}\n\n/**\n * Calculate contrast ratio between two colors (WCAG formula)\n *\n * @param hex1 - First color (hex)\n * @param hex2 - Second color (hex)\n * @returns Contrast ratio (1-21)\n *\n * @example\n * ```ts\n * const ratio = getContrastRatio('#ffffff', '#000000');\n * // Returns: 21 (maximum contrast)\n * ```\n */\nexport function getContrastRatio(hex1: string, hex2: string): number {\n const rgb1 = hexToRgb(hex1);\n const rgb2 = hexToRgb(hex2);\n\n if (!rgb1 || !rgb2) return 0;\n\n const lum1 = getLuminance(rgb1.r, rgb1.g, rgb1.b);\n const lum2 = getLuminance(rgb2.r, rgb2.g, rgb2.b);\n\n const lighter = Math.max(lum1, lum2);\n const darker = Math.min(lum1, lum2);\n\n return (lighter + 0.05) / (darker + 0.05);\n}\n\n/**\n * Check if color pair meets WCAG AA contrast requirements\n *\n * @param foreground - Foreground color (hex)\n * @param background - Background color (hex)\n * @param level - WCAG level ('AA' or 'AAA')\n * @param size - Text size ('normal' or 'large')\n * @returns true if contrast ratio meets requirements\n *\n * @example\n * ```ts\n * const isAccessible = meetsContrastRequirements('#000000', '#ffffff', 'AA', 'normal');\n * // Returns: true\n * ```\n */\nexport function meetsContrastRequirements(\n foreground: string,\n background: string,\n level: 'AA' | 'AAA' = 'AA',\n size: 'normal' | 'large' = 'normal'\n): boolean {\n const ratio = getContrastRatio(foreground, background);\n\n const requirements = {\n AA: { normal: 4.5, large: 3 },\n AAA: { normal: 7, large: 4.5 },\n };\n\n return ratio >= requirements[level][size];\n}\n\n/**\n * Convert hex to HSL for manipulation\n */\nexport function hexToHSL(hex: string): { h: number; s: number; l: number } {\n const rgb = hexToRgb(hex);\n if (!rgb) return { h: 0, s: 0, l: 0 };\n\n const r = rgb.r / 255;\n const g = rgb.g / 255;\n const b = rgb.b / 255;\n\n const max = Math.max(r, g, b);\n const min = Math.min(r, g, b);\n let h = 0, s = 0, l = (max + min) / 2;\n\n if (max !== min) {\n const d = max - min;\n s = l > 0.5 ? d / (2 - max - min) : d / (max + min);\n\n switch (max) {\n case r: h = ((g - b) / d + (g < b ? 6 : 0)) / 6; break;\n case g: h = ((b - r) / d + 2) / 6; break;\n case b: h = ((r - g) / d + 4) / 6; break;\n }\n }\n\n return {\n h: Math.round(h * 360),\n s: Math.round(s * 100),\n l: Math.round(l * 100),\n };\n}\n\n/**\n * Convert HSL to hex\n */\nexport function hslToHex(h: number, s: number, l: number): string {\n h = h / 360;\n s = s / 100;\n l = l / 100;\n\n let r, g, b;\n\n if (s === 0) {\n r = g = b = l;\n } else {\n const hue2rgb = (p: number, q: number, t: number) => {\n if (t < 0) t += 1;\n if (t > 1) t -= 1;\n if (t < 1/6) return p + (q - p) * 6 * t;\n if (t < 1/2) return q;\n if (t < 2/3) return p + (q - p) * (2/3 - t) * 6;\n return p;\n };\n\n const q = l < 0.5 ? l * (1 + s) : l + s - l * s;\n const p = 2 * l - q;\n\n r = hue2rgb(p, q, h + 1/3);\n g = hue2rgb(p, q, h);\n b = hue2rgb(p, q, h - 1/3);\n }\n\n const toHex = (x: number) => {\n const hex = Math.round(x * 255).toString(16);\n return hex.length === 1 ? '0' + hex : hex;\n };\n\n return `#${toHex(r)}${toHex(g)}${toHex(b)}`;\n}\n\n/**\n * Adjust lightness of a hex color\n * @param hex - Input color\n * @param percent - Amount to adjust (-100 to 100)\n */\nexport function adjustLightness(hex: string, percent: number): string {\n const hsl = hexToHSL(hex);\n const newL = Math.max(0, Math.min(100, hsl.l + percent));\n return hslToHex(hsl.h, hsl.s, newL);\n}\n\n/**\n * Adjust saturation of a hex color\n * @param hex - Input color\n * @param percent - Amount to adjust (-100 to 100)\n */\nexport function adjustSaturation(hex: string, percent: number): string {\n const hsl = hexToHSL(hex);\n const newS = Math.max(0, Math.min(100, hsl.s + percent));\n return hslToHex(hsl.h, newS, hsl.l);\n}\n\n/**\n * Rotate hue of a hex color\n * @param hex - Input color\n * @param degrees - Degrees to rotate (0-360)\n */\nexport function rotateHue(hex: string, degrees: number): string {\n const hsl = hexToHSL(hex);\n const newH = (hsl.h + degrees) % 360;\n return hslToHex(newH, hsl.s, hsl.l);\n}\n\n/**\n * Add opacity to a hex color (returns rgba CSS value)\n * @param hex - Input color\n * @param opacity - Opacity (0-1)\n */\nexport function adjustOpacity(hex: string, opacity: number): string {\n const rgb = hexToRgb(hex);\n if (!rgb) return hex;\n return `rgba(${rgb.r}, ${rgb.g}, ${rgb.b}, ${opacity})`;\n}\n\n/**\n * Get optimal foreground color (white or black) for a background\n * Uses WCAG contrast formula\n */\nexport function getOptimalForeground(\n bgHex: string,\n whiteHex: string = '#ffffff',\n blackHex: string = '#000000'\n): string {\n const whiteRatio = getContrastRatio(bgHex, whiteHex);\n const blackRatio = getContrastRatio(bgHex, blackHex);\n\n return whiteRatio > blackRatio ? whiteHex : blackHex;\n}\n\n/**\n * Generate a complete tint/shade scale (like Tailwind)\n * Returns 50, 100, 200, ..., 900 variants\n */\nexport function generateColorScale(baseHex: string): Record<number, string> {\n const hsl = hexToHSL(baseHex);\n\n return {\n 50: hslToHex(hsl.h, Math.max(hsl.s - 10, 20), 95),\n 100: hslToHex(hsl.h, Math.max(hsl.s - 5, 30), 90),\n 200: hslToHex(hsl.h, hsl.s, 80),\n 300: hslToHex(hsl.h, hsl.s, 70),\n 400: hslToHex(hsl.h, hsl.s, 60),\n 500: baseHex, // Base color\n 600: hslToHex(hsl.h, Math.min(hsl.s + 5, 100), 45),\n 700: hslToHex(hsl.h, Math.min(hsl.s + 10, 100), 35),\n 800: hslToHex(hsl.h, Math.min(hsl.s + 15, 100), 25),\n 900: hslToHex(hsl.h, Math.min(hsl.s + 20, 100), 15),\n };\n}\n\n/**\n * Color utilities for common operations\n */\nexport const colorUtils = {\n getCSSVariable,\n setCSSVariable,\n getForegroundColor,\n getSemanticColorPair,\n hexToRgb,\n hexToHSL,\n hslToHex,\n adjustLightness,\n adjustSaturation,\n rotateHue,\n adjustOpacity,\n getOptimalForeground,\n generateColorScale,\n getContrastRatio,\n meetsContrastRequirements,\n} as const;\n","import { type ClassValue, clsx } from \"clsx\";\nimport { twMerge } from \"tailwind-merge\";\n\nexport function cn(...inputs: ClassValue[]) {\n return twMerge(clsx(inputs));\n}\n","/**\n * Form Validation Utilities\n *\n * Simple validation helpers for form fields.\n * Works seamlessly with FormField and other form components.\n */\n\nexport type ValidationRule = {\n validate: (value: any) => boolean;\n message: string;\n};\n\nexport type FieldValidation = {\n required?: boolean | string;\n minLength?: { value: number; message: string };\n maxLength?: { value: number; message: string };\n pattern?: { value: RegExp; message: string };\n custom?: ValidationRule[];\n};\n\nexport type FormErrors = Record<string, string | undefined>;\n\n/**\n * Common validation patterns\n */\nexport const patterns = {\n email: {\n value: /^[A-Z0-9._%+-]+@[A-Z0-9.-]+\\.[A-Z]{2,}$/i,\n message: 'Invalid email address',\n },\n url: {\n value: /^https?:\\/\\/.+\\..+/,\n message: 'Invalid URL',\n },\n phone: {\n value: /^[\\d\\s\\-\\+\\(\\)]+$/,\n message: 'Invalid phone number',\n },\n alphanumeric: {\n value: /^[a-zA-Z0-9]+$/,\n message: 'Only letters and numbers allowed',\n },\n noSpaces: {\n value: /^\\S+$/,\n message: 'Spaces are not allowed',\n },\n};\n\n/**\n * Validate a single field value against validation rules\n *\n * @param value - The field value to validate\n * @param rules - Validation rules to apply\n * @returns Error message if validation fails, undefined if valid\n *\n * @example\n * ```tsx\n * const error = validateField(email, {\n * required: true,\n * pattern: patterns.email\n * });\n * ```\n */\nexport function validateField(\n value: any,\n rules: FieldValidation\n): string | undefined {\n // Required check\n if (rules.required) {\n const isEmpty =\n value === undefined ||\n value === null ||\n value === '' ||\n (Array.isArray(value) && value.length === 0);\n\n if (isEmpty) {\n return typeof rules.required === 'string'\n ? rules.required\n : 'This field is required';\n }\n }\n\n // Skip other validations if value is empty and not required\n if (!value && !rules.required) {\n return undefined;\n }\n\n // Min length check\n if (rules.minLength && value.length < rules.minLength.value) {\n return rules.minLength.message;\n }\n\n // Max length check\n if (rules.maxLength && value.length > rules.maxLength.value) {\n return rules.maxLength.message;\n }\n\n // Pattern check\n if (rules.pattern && !rules.pattern.value.test(value)) {\n return rules.pattern.message;\n }\n\n // Custom validations\n if (rules.custom) {\n for (const rule of rules.custom) {\n if (!rule.validate(value)) {\n return rule.message;\n }\n }\n }\n\n return undefined;\n}\n\n/**\n * Validate all fields in a form\n *\n * @param values - Object containing all form field values\n * @param validations - Object containing validation rules for each field\n * @returns Object containing errors for each field\n *\n * @example\n * ```tsx\n * const errors = validateForm(\n * { email: 'test', password: '123' },\n * {\n * email: { required: true, pattern: patterns.email },\n * password: { required: true, minLength: { value: 8, message: 'Min 8 chars' } }\n * }\n * );\n * // errors = { email: 'Invalid email address', password: 'Min 8 chars' }\n * ```\n */\nexport function validateForm(\n values: Record<string, any>,\n validations: Record<string, FieldValidation>\n): FormErrors {\n const errors: FormErrors = {};\n\n for (const [field, rules] of Object.entries(validations)) {\n const error = validateField(values[field], rules);\n if (error) {\n errors[field] = error;\n }\n }\n\n return errors;\n}\n\n/**\n * Check if form has any errors\n *\n * @param errors - Form errors object\n * @returns true if there are any errors\n *\n * @example\n * ```tsx\n * if (hasErrors(errors)) {\n * console.log('Form has errors');\n * }\n * ```\n */\nexport function hasErrors(errors: FormErrors): boolean {\n return Object.values(errors).some((error) => error !== undefined);\n}\n\n/**\n * Common validation rule builders\n */\nexport const rules = {\n required: (message = 'This field is required'): FieldValidation => ({\n required: message,\n }),\n\n email: (message = 'Invalid email address'): FieldValidation => ({\n pattern: { value: patterns.email.value, message },\n }),\n\n minLength: (length: number, message?: string): FieldValidation => ({\n minLength: {\n value: length,\n message: message || `Minimum ${length} characters required`,\n },\n }),\n\n maxLength: (length: number, message?: string): FieldValidation => ({\n maxLength: {\n value: length,\n message: message || `Maximum ${length} characters allowed`,\n },\n }),\n\n match: (\n otherValue: any,\n message = 'Values do not match'\n ): FieldValidation => ({\n custom: [\n {\n validate: (value) => value === otherValue,\n message,\n },\n ],\n }),\n};\n","/**\n * Syntax Parser Patterns\n * Regex patterns for tokenizing TypeScript/JavaScript/JSX code\n */\n\n/**\n * Token pattern configuration\n * Order matters - patterns are tested in sequence\n */\nexport const TOKEN_PATTERNS = [\n // Single-line comments\n { type: 'comment' as const, pattern: /\\/\\/.*$/gm },\n\n // Multi-line comments\n { type: 'comment' as const, pattern: /\\/\\*[\\s\\S]*?\\*\\//g },\n\n // Template literals and strings\n { type: 'string' as const, pattern: /`(?:\\\\.|[^`\\\\])*`/g },\n { type: 'string' as const, pattern: /\"(?:\\\\.|[^\"\\\\])*\"/g },\n { type: 'string' as const, pattern: /'(?:\\\\.|[^'\\\\])*'/g },\n\n // JSX/TSX tags\n { type: 'tag' as const, pattern: /<\\/?[A-Z][a-zA-Z0-9]*(?=[\\s>])/g },\n { type: 'tag' as const, pattern: /<\\/?[a-z][a-zA-Z0-9-]*(?=[\\s>])/g },\n\n // Keywords\n {\n type: 'keyword' as const,\n pattern: /\\b(const|let|var|function|return|if|else|for|while|do|switch|case|break|continue|throw|try|catch|finally|new|typeof|instanceof|void|delete|async|await|yield|export|import|from|default|class|extends|implements|interface|type|enum|namespace|declare|public|private|protected|static|readonly|abstract|as|is|in|of|null|undefined)\\b/g\n },\n\n // Booleans\n { type: 'boolean' as const, pattern: /\\b(true|false)\\b/g },\n\n // Numbers\n { type: 'number' as const, pattern: /\\b\\d+\\.?\\d*(?:e[+-]?\\d+)?(?:n)?\\b/gi },\n { type: 'number' as const, pattern: /\\b0x[0-9a-f]+\\b/gi },\n\n // Function calls\n { type: 'function' as const, pattern: /\\b[a-zA-Z_$][a-zA-Z0-9_$]*(?=\\s*\\()/g },\n\n // Class names (PascalCase identifiers)\n { type: 'className' as const, pattern: /\\b[A-Z][a-zA-Z0-9]*\\b/g },\n\n // JSX attributes\n { type: 'attribute' as const, pattern: /\\b[a-z][a-zA-Z0-9]*(?=\\s*=)/g },\n\n // Object properties (after dot)\n { type: 'property' as const, pattern: /(?<=\\.)[a-zA-Z_$][a-zA-Z0-9_$]*/g },\n\n // Operators\n {\n type: 'operator' as const,\n pattern: /[+\\-*/%=!<>&|^~?:]+|&&|\\|\\||\\.\\.\\.|\\?\\?|===|!==|==|!=|<=|>=|<<|>>|>>>/g\n },\n\n // Punctuation\n { type: 'punctuation' as const, pattern: /[{}[\\](),.;]/g },\n] as const;\n\n/**\n * Characters that should be treated as whitespace\n */\nexport const WHITESPACE = /\\s+/g;\n","/**\n * Syntax Tokenizer\n * Core tokenization logic for parsing code into syntax tokens\n */\n\nimport { SyntaxToken, Language } from './types';\nimport { TOKEN_PATTERNS } from './patterns';\n\ninterface Match {\n text: string;\n type: SyntaxToken['type'];\n index: number;\n}\n\n/**\n * Tokenizes source code into an array of syntax tokens\n *\n * @param code - The source code to tokenize\n * @param language - The programming language (currently only affects metadata, all use same patterns)\n * @returns Array of syntax tokens with text and type information\n *\n * @example\n * ```ts\n * const tokens = tokenize('const greeting = \"Hello\";');\n * // Returns:\n * // [\n * // { text: 'const', type: 'keyword' },\n * // { text: ' ', type: 'plain' },\n * // { text: 'greeting', type: 'plain' },\n * // { text: ' ', type: 'plain' },\n * // { text: '=', type: 'operator' },\n * // { text: ' ', type: 'plain' },\n * // { text: '\"Hello\"', type: 'string' },\n * // { text: ';', type: 'punctuation' },\n * // ]\n * ```\n */\nexport function tokenize(code: string, language: Language = 'typescript'): SyntaxToken[] {\n // If empty, return plain token\n if (!code || code.trim() === '') {\n return [{ text: code, type: 'plain' }];\n }\n\n // Collect all matches from all patterns\n const matches: Match[] = [];\n\n for (const { type, pattern } of TOKEN_PATTERNS) {\n // Reset regex lastIndex\n pattern.lastIndex = 0;\n\n let match;\n while ((match = pattern.exec(code)) !== null) {\n matches.push({\n text: match[0],\n type,\n index: match.index,\n });\n }\n }\n\n // Sort matches by position\n matches.sort((a, b) => a.index - b.index);\n\n // Remove overlapping matches (keep first match at each position)\n const nonOverlapping: Match[] = [];\n let lastEnd = 0;\n\n for (const match of matches) {\n if (match.index >= lastEnd) {\n nonOverlapping.push(match);\n lastEnd = match.index + match.text.length;\n }\n }\n\n // Build tokens array, filling gaps with plain text\n const tokens: SyntaxToken[] = [];\n let position = 0;\n\n for (const match of nonOverlapping) {\n // Add plain text before this match\n if (match.index > position) {\n const plainText = code.slice(position, match.index);\n tokens.push({ text: plainText, type: 'plain' });\n }\n\n // Add the matched token\n tokens.push({ text: match.text, type: match.type });\n position = match.index + match.text.length;\n }\n\n // Add any remaining plain text\n if (position < code.length) {\n tokens.push({ text: code.slice(position), type: 'plain' });\n }\n\n return tokens;\n}\n\n/**\n * Detects the language from code content or file extension\n * Currently returns 'typescript' for all cases as patterns support TS/JS/JSX/TSX\n *\n * @param code - The source code\n * @param filename - Optional filename for extension detection\n * @returns Detected language\n */\nexport function detectLanguage(code: string, filename?: string): Language {\n // For now, treat everything as TypeScript since our patterns support all variants\n // Future: Could detect based on JSX syntax or file extension\n if (filename) {\n if (filename.endsWith('.tsx')) return 'tsx';\n if (filename.endsWith('.jsx')) return 'jsx';\n if (filename.endsWith('.js')) return 'javascript';\n }\n\n return 'typescript';\n}\n","/**\n * Syntax Parser\n *\n * Lightweight syntax parser for automatic code tokenization.\n * Converts plain code strings into syntax-highlighted token arrays.\n *\n * @example\n * ```ts\n * import { parseCode } from '@sage/ui';\n *\n * const tokens = parseCode('const greeting = \"Hello World\";');\n * // Use with CollapsibleCodeBlock:\n * <CollapsibleCodeBlock\n * id=\"example\"\n * code={tokens}\n * />\n * ```\n */\n\nexport { tokenize, detectLanguage } from './tokenizer';\nexport type { SyntaxToken, SyntaxType, Language } from './types';\n\nimport { tokenize, detectLanguage } from './tokenizer';\nimport type { SyntaxToken, Language } from './types';\n\n/**\n * Parses source code into syntax tokens for highlighting\n *\n * @param code - The source code to parse\n * @param language - Optional language hint (auto-detected if not provided)\n * @returns Array of syntax tokens ready for CollapsibleCodeBlock\n *\n * @example\n * ```ts\n * const code = `\n * import { useState } from 'react';\n *\n * export function Counter() {\n * const [count, setCount] = useState(0);\n * return <button onClick={() => setCount(count + 1)}>{count}</button>;\n * }\n * `;\n *\n * const tokens = parseCode(code);\n * ```\n */\nexport function parseCode(code: string, language?: Language): SyntaxToken[] {\n const lang = language || detectLanguage(code);\n return tokenize(code, lang);\n}\n"],"mappings":"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","names":["p","q","rules"]}
@@ -0,0 +1,114 @@
1
+ /**
2
+ * Form Validation Utilities
3
+ *
4
+ * Simple validation helpers for form fields.
5
+ * Works seamlessly with FormField and other form components.
6
+ */
7
+ type ValidationRule = {
8
+ validate: (value: any) => boolean;
9
+ message: string;
10
+ };
11
+ type FieldValidation = {
12
+ required?: boolean | string;
13
+ minLength?: {
14
+ value: number;
15
+ message: string;
16
+ };
17
+ maxLength?: {
18
+ value: number;
19
+ message: string;
20
+ };
21
+ pattern?: {
22
+ value: RegExp;
23
+ message: string;
24
+ };
25
+ custom?: ValidationRule[];
26
+ };
27
+ type FormErrors = Record<string, string | undefined>;
28
+ /**
29
+ * Common validation patterns
30
+ */
31
+ declare const patterns: {
32
+ email: {
33
+ value: RegExp;
34
+ message: string;
35
+ };
36
+ url: {
37
+ value: RegExp;
38
+ message: string;
39
+ };
40
+ phone: {
41
+ value: RegExp;
42
+ message: string;
43
+ };
44
+ alphanumeric: {
45
+ value: RegExp;
46
+ message: string;
47
+ };
48
+ noSpaces: {
49
+ value: RegExp;
50
+ message: string;
51
+ };
52
+ };
53
+ /**
54
+ * Validate a single field value against validation rules
55
+ *
56
+ * @param value - The field value to validate
57
+ * @param rules - Validation rules to apply
58
+ * @returns Error message if validation fails, undefined if valid
59
+ *
60
+ * @example
61
+ * ```tsx
62
+ * const error = validateField(email, {
63
+ * required: true,
64
+ * pattern: patterns.email
65
+ * });
66
+ * ```
67
+ */
68
+ declare function validateField(value: any, rules: FieldValidation): string | undefined;
69
+ /**
70
+ * Validate all fields in a form
71
+ *
72
+ * @param values - Object containing all form field values
73
+ * @param validations - Object containing validation rules for each field
74
+ * @returns Object containing errors for each field
75
+ *
76
+ * @example
77
+ * ```tsx
78
+ * const errors = validateForm(
79
+ * { email: 'test', password: '123' },
80
+ * {
81
+ * email: { required: true, pattern: patterns.email },
82
+ * password: { required: true, minLength: { value: 8, message: 'Min 8 chars' } }
83
+ * }
84
+ * );
85
+ * // errors = { email: 'Invalid email address', password: 'Min 8 chars' }
86
+ * ```
87
+ */
88
+ declare function validateForm(values: Record<string, any>, validations: Record<string, FieldValidation>): FormErrors;
89
+ /**
90
+ * Check if form has any errors
91
+ *
92
+ * @param errors - Form errors object
93
+ * @returns true if there are any errors
94
+ *
95
+ * @example
96
+ * ```tsx
97
+ * if (hasErrors(errors)) {
98
+ * console.log('Form has errors');
99
+ * }
100
+ * ```
101
+ */
102
+ declare function hasErrors(errors: FormErrors): boolean;
103
+ /**
104
+ * Common validation rule builders
105
+ */
106
+ declare const rules: {
107
+ required: (message?: string) => FieldValidation;
108
+ email: (message?: string) => FieldValidation;
109
+ minLength: (length: number, message?: string) => FieldValidation;
110
+ maxLength: (length: number, message?: string) => FieldValidation;
111
+ match: (otherValue: any, message?: string) => FieldValidation;
112
+ };
113
+
114
+ export { type FieldValidation as F, type ValidationRule as V, type FormErrors as a, validateForm as b, hasErrors as h, patterns as p, rules as r, validateField as v };
@@ -0,0 +1,114 @@
1
+ /**
2
+ * Form Validation Utilities
3
+ *
4
+ * Simple validation helpers for form fields.
5
+ * Works seamlessly with FormField and other form components.
6
+ */
7
+ type ValidationRule = {
8
+ validate: (value: any) => boolean;
9
+ message: string;
10
+ };
11
+ type FieldValidation = {
12
+ required?: boolean | string;
13
+ minLength?: {
14
+ value: number;
15
+ message: string;
16
+ };
17
+ maxLength?: {
18
+ value: number;
19
+ message: string;
20
+ };
21
+ pattern?: {
22
+ value: RegExp;
23
+ message: string;
24
+ };
25
+ custom?: ValidationRule[];
26
+ };
27
+ type FormErrors = Record<string, string | undefined>;
28
+ /**
29
+ * Common validation patterns
30
+ */
31
+ declare const patterns: {
32
+ email: {
33
+ value: RegExp;
34
+ message: string;
35
+ };
36
+ url: {
37
+ value: RegExp;
38
+ message: string;
39
+ };
40
+ phone: {
41
+ value: RegExp;
42
+ message: string;
43
+ };
44
+ alphanumeric: {
45
+ value: RegExp;
46
+ message: string;
47
+ };
48
+ noSpaces: {
49
+ value: RegExp;
50
+ message: string;
51
+ };
52
+ };
53
+ /**
54
+ * Validate a single field value against validation rules
55
+ *
56
+ * @param value - The field value to validate
57
+ * @param rules - Validation rules to apply
58
+ * @returns Error message if validation fails, undefined if valid
59
+ *
60
+ * @example
61
+ * ```tsx
62
+ * const error = validateField(email, {
63
+ * required: true,
64
+ * pattern: patterns.email
65
+ * });
66
+ * ```
67
+ */
68
+ declare function validateField(value: any, rules: FieldValidation): string | undefined;
69
+ /**
70
+ * Validate all fields in a form
71
+ *
72
+ * @param values - Object containing all form field values
73
+ * @param validations - Object containing validation rules for each field
74
+ * @returns Object containing errors for each field
75
+ *
76
+ * @example
77
+ * ```tsx
78
+ * const errors = validateForm(
79
+ * { email: 'test', password: '123' },
80
+ * {
81
+ * email: { required: true, pattern: patterns.email },
82
+ * password: { required: true, minLength: { value: 8, message: 'Min 8 chars' } }
83
+ * }
84
+ * );
85
+ * // errors = { email: 'Invalid email address', password: 'Min 8 chars' }
86
+ * ```
87
+ */
88
+ declare function validateForm(values: Record<string, any>, validations: Record<string, FieldValidation>): FormErrors;
89
+ /**
90
+ * Check if form has any errors
91
+ *
92
+ * @param errors - Form errors object
93
+ * @returns true if there are any errors
94
+ *
95
+ * @example
96
+ * ```tsx
97
+ * if (hasErrors(errors)) {
98
+ * console.log('Form has errors');
99
+ * }
100
+ * ```
101
+ */
102
+ declare function hasErrors(errors: FormErrors): boolean;
103
+ /**
104
+ * Common validation rule builders
105
+ */
106
+ declare const rules: {
107
+ required: (message?: string) => FieldValidation;
108
+ email: (message?: string) => FieldValidation;
109
+ minLength: (length: number, message?: string) => FieldValidation;
110
+ maxLength: (length: number, message?: string) => FieldValidation;
111
+ match: (otherValue: any, message?: string) => FieldValidation;
112
+ };
113
+
114
+ export { type FieldValidation as F, type ValidationRule as V, type FormErrors as a, validateForm as b, hasErrors as h, patterns as p, rules as r, validateField as v };
package/package.json ADDED
@@ -0,0 +1,118 @@
1
+ {
2
+ "name": "@shalomormsby/ui",
3
+ "version": "0.0.5",
4
+ "main": "dist/index.js",
5
+ "module": "dist/index.mjs",
6
+ "types": "dist/index.d.ts",
7
+ "sideEffects": false,
8
+ "license": "MIT",
9
+ "author": "Shalom Ormsby",
10
+ "repository": {
11
+ "type": "git",
12
+ "url": "https://github.com/shalomormsby/ecosystem.git",
13
+ "directory": "packages/ui"
14
+ },
15
+ "homepage": "https://ui.shalomormsby.com",
16
+ "bugs": "https://github.com/shalomormsby/ecosystem/issues",
17
+ "publishConfig": {
18
+ "access": "public"
19
+ },
20
+ "files": [
21
+ "dist",
22
+ "README.md"
23
+ ],
24
+ "exports": {
25
+ ".": {
26
+ "types": "./dist/index.d.ts",
27
+ "import": "./dist/index.mjs",
28
+ "require": "./dist/index.js"
29
+ },
30
+ "./tokens": {
31
+ "types": "./dist/tokens.d.ts",
32
+ "import": "./dist/tokens.mjs",
33
+ "require": "./dist/tokens.js"
34
+ },
35
+ "./hooks": {
36
+ "types": "./dist/hooks.d.ts",
37
+ "import": "./dist/hooks.mjs",
38
+ "require": "./dist/hooks.js"
39
+ },
40
+ "./utils": {
41
+ "types": "./dist/utils.d.ts",
42
+ "import": "./dist/utils.mjs",
43
+ "require": "./dist/utils.js"
44
+ },
45
+ "./providers": {
46
+ "types": "./dist/providers.d.ts",
47
+ "import": "./dist/providers.mjs",
48
+ "require": "./dist/providers.js"
49
+ }
50
+ },
51
+ "scripts": {
52
+ "build": "tsup src/index.ts src/tokens.ts src/hooks.ts src/utils.ts src/providers.ts --format esm,cjs --dts",
53
+ "dev": "tsup src/index.ts src/tokens.ts src/hooks.ts src/utils.ts src/providers.ts --format esm,cjs --dts --watch",
54
+ "lint": "eslint src/"
55
+ },
56
+ "peerDependencies": {
57
+ "framer-motion": "*",
58
+ "react": "*"
59
+ },
60
+ "dependencies": {
61
+ "@dnd-kit/core": "^6.3.1",
62
+ "@dnd-kit/sortable": "^10.0.0",
63
+ "@dnd-kit/utilities": "^3.2.2",
64
+ "@hookform/resolvers": "^5.2.2",
65
+ "@radix-ui/react-accordion": "^1.2.12",
66
+ "@radix-ui/react-alert-dialog": "^1.1.15",
67
+ "@radix-ui/react-aspect-ratio": "^1.1.8",
68
+ "@radix-ui/react-avatar": "^1.1.11",
69
+ "@radix-ui/react-checkbox": "^1.3.3",
70
+ "@radix-ui/react-collapsible": "^1.1.12",
71
+ "@radix-ui/react-context-menu": "^2.2.16",
72
+ "@radix-ui/react-dialog": "^1.1.15",
73
+ "@radix-ui/react-dropdown-menu": "^2.1.16",
74
+ "@radix-ui/react-hover-card": "^1.1.15",
75
+ "@radix-ui/react-label": "^2.1.8",
76
+ "@radix-ui/react-menubar": "^1.1.16",
77
+ "@radix-ui/react-navigation-menu": "^1.2.14",
78
+ "@radix-ui/react-popover": "^1.1.15",
79
+ "@radix-ui/react-progress": "^1.1.8",
80
+ "@radix-ui/react-radio-group": "^1.3.8",
81
+ "@radix-ui/react-scroll-area": "^1.2.10",
82
+ "@radix-ui/react-select": "^2.2.6",
83
+ "@radix-ui/react-separator": "^1.1.8",
84
+ "@radix-ui/react-slider": "^1.3.6",
85
+ "@radix-ui/react-slot": "^1.2.4",
86
+ "@radix-ui/react-switch": "^1.2.6",
87
+ "@radix-ui/react-tabs": "^1.1.13",
88
+ "@radix-ui/react-toggle": "^1.1.10",
89
+ "@radix-ui/react-toggle-group": "^1.1.11",
90
+ "@radix-ui/react-tooltip": "^1.2.8",
91
+ "@sage/tokens": "workspace:*",
92
+ "@tanstack/react-table": "^8.21.3",
93
+ "class-variance-authority": "^0.7.0",
94
+ "clsx": "^2.1.0",
95
+ "cmdk": "^1.1.1",
96
+ "date-fns": "^4.1.0",
97
+ "embla-carousel-react": "^8.6.0",
98
+ "input-otp": "^1.4.2",
99
+ "lucide-react": "^0.562.0",
100
+ "ogl": "^1.0.11",
101
+ "react-day-picker": "^9.13.0",
102
+ "react-hook-form": "^7.70.0",
103
+ "react-resizable-panels": "^4.4.0",
104
+ "sonner": "^2.0.7",
105
+ "tailwind-merge": "^2.2.0",
106
+ "vaul": "^1.1.2",
107
+ "zod": "^3.25.76",
108
+ "zustand": "^5.0.9"
109
+ },
110
+ "devDependencies": {
111
+ "@sage/config": "workspace:*",
112
+ "@types/react": "^19.0.0",
113
+ "framer-motion": "^12.26.2",
114
+ "tailwindcss": "^3.4.0",
115
+ "tsup": "^8.0.0",
116
+ "typescript": "^5.0.0"
117
+ }
118
+ }