mirror of
https://github.com/johndoe6345789/low-code-react-app-b.git
synced 2026-04-24 13:44:54 +00:00
Migration complete for: - 5 atoms: Accordion, CopyButton, FileUpload, FilterInput, Image, Input, PasswordInput, Popover (8 total) - 1 molecule: BindingEditor Changes: - Deleted 9 legacy TSX files that have complete JSON equivalents - Exported BindingEditor from json-components.ts with useBindingEditor hook - Registered useBindingEditor in hooks-registry.ts - Updated all imports across codebase to use JSON-based components - Fixed build errors: schema-loader dynamic import, DataSourceGroupSection - Cleaned up component index exports Build status: ✅ PASSING - 0 TypeScript errors - All 9,408 modules transformed successfully - No blocking build warnings Next steps: - 3 organisms still need conversion: DataSourceManager, NavigationMenu, TreeListPanel - 120+ additional components have TSX versions (need individual migration) - 22 JSON components now available for use throughout the app Co-Authored-By: Claude Haiku 4.5 <noreply@anthropic.com>
72 lines
1.8 KiB
TypeScript
72 lines
1.8 KiB
TypeScript
import { Star } from '@phosphor-icons/react'
|
|
import { cn } from '@/lib/utils'
|
|
|
|
interface RatingProps {
|
|
value: number
|
|
onChange?: (value: number) => void
|
|
max?: number
|
|
size?: 'sm' | 'md' | 'lg'
|
|
readonly?: boolean
|
|
showValue?: boolean
|
|
className?: string
|
|
}
|
|
|
|
export function Rating({
|
|
value,
|
|
onChange,
|
|
max = 5,
|
|
size = 'md',
|
|
readonly = false,
|
|
showValue = false,
|
|
className
|
|
}: RatingProps) {
|
|
const sizeStyles = {
|
|
sm: 16,
|
|
md: 20,
|
|
lg: 24,
|
|
}
|
|
|
|
const iconSize = sizeStyles[size]
|
|
|
|
return (
|
|
<div className={cn('flex items-center gap-2', className)}>
|
|
<div className="flex items-center gap-0.5">
|
|
{Array.from({ length: max }, (_, index) => {
|
|
const starValue = index + 1
|
|
const isFilled = starValue <= value
|
|
const isHalfFilled = starValue - 0.5 === value
|
|
|
|
return (
|
|
<button
|
|
key={index}
|
|
type="button"
|
|
onClick={() => !readonly && onChange?.(starValue)}
|
|
disabled={readonly}
|
|
className={cn(
|
|
'transition-colors',
|
|
!readonly && 'cursor-pointer hover:scale-110',
|
|
readonly && 'cursor-default'
|
|
)}
|
|
aria-label={`Rate ${starValue} out of ${max}`}
|
|
>
|
|
<Star
|
|
size={iconSize}
|
|
weight={isFilled ? 'fill' : 'regular'}
|
|
className={cn(
|
|
'transition-colors',
|
|
isFilled ? 'text-accent fill-accent' : 'text-muted'
|
|
)}
|
|
/>
|
|
</button>
|
|
)
|
|
})}
|
|
</div>
|
|
{showValue && (
|
|
<span className="text-sm font-medium text-muted-foreground">
|
|
{value.toFixed(1)} / {max}
|
|
</span>
|
|
)}
|
|
</div>
|
|
)
|
|
}
|