diff --git a/src/components/Slider/Slider.tsx b/src/components/Slider/Slider.tsx
new file mode 100644
index 0000000000..7399041654
--- /dev/null
+++ b/src/components/Slider/Slider.tsx
@@ -0,0 +1,137 @@
+import * as React from 'react';
+import { StyleSheet, View, ViewStyle } from 'react-native';
+
+import type { SliderProps } from './types';
+import { useInternalTheme } from '../../core/theming';
+
+const clamp = (v: number, min: number, max: number) =>
+ Math.min(Math.max(v, min), max);
+
+const round = (v: number, step: number) => {
+ if (!step) return v;
+ return Math.round(v / step) * step;
+};
+
+const styles = StyleSheet.create({
+ container: {
+ height: 48,
+ justifyContent: 'center',
+ paddingVertical: 12,
+ } as ViewStyle,
+ track: {
+ height: 4,
+ borderRadius: 2,
+ overflow: 'hidden',
+ position: 'relative',
+ } as ViewStyle,
+ thumb: {
+ position: 'absolute',
+ width: 16,
+ height: 16,
+ borderRadius: 8,
+ top: -6,
+ marginLeft: -8,
+ } as ViewStyle,
+});
+
+/**
+ * Material 3 Slider.
+ *
+ * A horizontal slider that lets the user pick a value between `min` and `max`
+ * by dragging or tapping the track. The thumb position reflects the
+ * controlled `value`.
+ *
+ * @param props
+ */
+function Slider({
+ value,
+ min = 0,
+ max = 1,
+ step,
+ onValueChange,
+ disabled = false,
+ color,
+ trackColor,
+ thumbColor,
+ style,
+ theme: themeOverrides,
+ testID = 'slider',
+}: SliderProps) {
+ const theme = useInternalTheme(themeOverrides);
+ const [width, setWidth] = React.useState(0);
+
+ const activeColor =
+ color ?? (theme.isV3 ? theme.colors.primary : theme.colors.accent);
+ const inactiveColor =
+ trackColor ?? (theme.isV3 ? theme.colors.surfaceVariant : '#bdbdbd');
+ const thumbTintColor = thumbColor ?? activeColor;
+
+ const span = Math.max(max - min, 1e-9);
+ const pct = clamp((value - min) / span, 0, 1);
+
+ const valueFromX = (x: number) => {
+ const ratio = width > 0 ? clamp(x / width, 0, 1) : 0;
+ let next = min + ratio * span;
+ if (step) next = min + round(next - min, step);
+ return clamp(next, min, max);
+ };
+
+ const handleResponder = (e: { nativeEvent: { locationX: number } }) => {
+ if (disabled || width <= 0) return;
+ onValueChange?.(valueFromX(e.nativeEvent.locationX));
+ };
+
+ const handleLayout = (e: { nativeEvent: { layout: { width: number } } }) => {
+ setWidth(e.nativeEvent.layout.width);
+ };
+
+ return (
+
+ !disabled}
+ onResponderGrant={handleResponder}
+ onResponderMove={handleResponder}
+ >
+
+
+
+
+ );
+}
+
+export default Slider;
diff --git a/src/components/Slider/types.ts b/src/components/Slider/types.ts
new file mode 100644
index 0000000000..8e863c725b
--- /dev/null
+++ b/src/components/Slider/types.ts
@@ -0,0 +1,30 @@
+import type { StyleProp, ViewStyle } from 'react-native';
+
+import type { ThemeProp } from '../../types';
+
+export type SliderProps = {
+ /** Current value of the slider (controlled). */
+ value: number;
+ /** Minimum value. @default 0 */
+ min?: number;
+ /** Maximum value. @default 1 */
+ max?: number;
+ /** Step size. When set, the value snaps to multiples of `step` from `min`. */
+ step?: number;
+ /** Called with the new value whenever the user drags or taps the track. */
+ onValueChange?: (value: number) => void;
+ /** Whether the slider is disabled (no interaction, dimmed thumb). */
+ disabled?: boolean;
+ /** Color of the active track (left of the thumb). Defaults to theme primary. */
+ color?: string;
+ /** Color of the inactive track. Defaults to a translucent track. */
+ trackColor?: string;
+ /** Color of the thumb. Defaults to the active color. */
+ thumbColor?: string;
+ /** Style applied to the container. */
+ style?: StyleProp;
+ /** @optional */
+ theme?: ThemeProp;
+ /** TestID for testing. */
+ testID?: string;
+};
diff --git a/src/index.tsx b/src/index.tsx
index 1b20528787..b399a14759 100644
--- a/src/index.tsx
+++ b/src/index.tsx
@@ -33,6 +33,7 @@ export { default as BottomNavigation } from './components/BottomNavigation/Botto
export { default as Button } from './components/Button/Button';
export { default as Card } from './components/Card/Card';
export { default as Checkbox } from './components/Checkbox';
+export { default as Slider } from './components/Slider/Slider';
export { default as Chip } from './components/Chip/Chip';
export { default as DataTable } from './components/DataTable/DataTable';
export { default as Dialog } from './components/Dialog/Dialog';
@@ -86,6 +87,7 @@ export type {
} from './components/BottomNavigation/BottomNavigation';
export type { Props as ButtonProps } from './components/Button/Button';
export type { Props as CardProps } from './components/Card/Card';
+export type { SliderProps } from './components/Slider/types';
export type { Props as CardActionsProps } from './components/Card/CardActions';
export type { Props as CardContentProps } from './components/Card/CardContent';
export type { Props as CardCoverProps } from './components/Card/CardCover';