+
+
+
+
+ {showValue && (
+
+ handleFromInputChange(e.target.value)}
+ onBlur={() => setTouched(config.key, true)}
+ className={inputNumberStyles}
+ />
+ handleToInputChange(e.target.value)}
+ onBlur={() => setTouched(config.key, true)}
+ className={inputNumberStyles}
+ />
+
+ )}
+
+ {/* Dual range slider container */}
+
+ {/* Track background */}
+
+
+ {/* Active range highlight */}
+
+
+ {/* From slider */}
+
handleFromChange(Number(e.target.value))}
+ onBlur={() => setTouched(config.key, true)}
+ className={`
+ formkit-range-slider-from
+ absolute top-0 w-full h-6
+ appearance-none bg-transparent
+ pointer-events-none
+ [&::-webkit-slider-thumb]:pointer-events-auto
+ [&::-moz-range-thumb]:pointer-events-auto
+ ${thumbStyles}
+ ${isDisabled ? 'opacity-50' : ''}
+ `}
+ />
+
+ {/* To slider */}
+
handleToChange(Number(e.target.value))}
+ onBlur={() => setTouched(config.key, true)}
+ className={`
+ formkit-range-slider-to
+ absolute top-0 w-full h-6
+ appearance-none bg-transparent
+ pointer-events-none
+ [&::-webkit-slider-thumb]:pointer-events-auto
+ [&::-moz-range-thumb]:pointer-events-auto
+ ${thumbStyles}
+ ${isDisabled ? 'opacity-50' : ''}
+ `}
+ />
+
+
+ {/* Min/Max labels */}
+
+ {min}
+ {max}
+
+
+ {config.description && !showError && (
+
+ {config.description}
+
+ )}
+
+ {showError &&
}
+
+ );
+}
+
+export type { Props as RangeSliderFieldProps };
diff --git a/src/components/fields/RatingField.tsx b/src/components/fields/RatingField.tsx
new file mode 100644
index 0000000..d73f156
--- /dev/null
+++ b/src/components/fields/RatingField.tsx
@@ -0,0 +1,246 @@
+/**
+ * RatingField - Star rating input component
+ */
+
+import { useState, type JSX, type KeyboardEvent } from 'react';
+import type { FieldConfig } from '../../models/FieldConfig';
+import { useFormKitContext } from '../context/FormKitContext';
+import { useI18n } from '../../hooks/useI18n';
+import FieldLabel from '../layout/FieldLabel';
+import FieldError from '../layout/FieldError';
+
+/**
+ * Props for RatingField
+ */
+type Props = {
+ config: FieldConfig;
+};
+
+/**
+ * Star icon component
+ */
+function StarIcon({ filled, half }: { filled: boolean; half?: boolean }): JSX.Element {
+ if (half) {
+ return (
+