@metamask/design-system-react-native 0.34.0 → 0.35.0

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.
Files changed (74) hide show
  1. package/CHANGELOG.md +18 -1
  2. package/dist/components/ActionListItem/ActionListItem.cjs +1 -1
  3. package/dist/components/ActionListItem/ActionListItem.cjs.map +1 -1
  4. package/dist/components/ActionListItem/ActionListItem.mjs +1 -1
  5. package/dist/components/ActionListItem/ActionListItem.mjs.map +1 -1
  6. package/dist/components/ButtonBase/ButtonBase.cjs +1 -1
  7. package/dist/components/ButtonBase/ButtonBase.cjs.map +1 -1
  8. package/dist/components/ButtonBase/ButtonBase.d.cts.map +1 -1
  9. package/dist/components/ButtonBase/ButtonBase.d.mts.map +1 -1
  10. package/dist/components/ButtonBase/ButtonBase.mjs +1 -1
  11. package/dist/components/ButtonBase/ButtonBase.mjs.map +1 -1
  12. package/dist/components/FilterButton/FilterButton.cjs +24 -36
  13. package/dist/components/FilterButton/FilterButton.cjs.map +1 -1
  14. package/dist/components/FilterButton/FilterButton.d.cts.map +1 -1
  15. package/dist/components/FilterButton/FilterButton.d.mts.map +1 -1
  16. package/dist/components/FilterButton/FilterButton.mjs +25 -37
  17. package/dist/components/FilterButton/FilterButton.mjs.map +1 -1
  18. package/dist/components/Slider/Slider.cjs +139 -0
  19. package/dist/components/Slider/Slider.cjs.map +1 -0
  20. package/dist/components/Slider/Slider.constants.cjs +36 -0
  21. package/dist/components/Slider/Slider.constants.cjs.map +1 -0
  22. package/dist/components/Slider/Slider.constants.d.cts +33 -0
  23. package/dist/components/Slider/Slider.constants.d.cts.map +1 -0
  24. package/dist/components/Slider/Slider.constants.d.mts +33 -0
  25. package/dist/components/Slider/Slider.constants.d.mts.map +1 -0
  26. package/dist/components/Slider/Slider.constants.mjs +33 -0
  27. package/dist/components/Slider/Slider.constants.mjs.map +1 -0
  28. package/dist/components/Slider/Slider.d.cts +7 -0
  29. package/dist/components/Slider/Slider.d.cts.map +1 -0
  30. package/dist/components/Slider/Slider.d.mts +7 -0
  31. package/dist/components/Slider/Slider.d.mts.map +1 -0
  32. package/dist/components/Slider/Slider.mjs +116 -0
  33. package/dist/components/Slider/Slider.mjs.map +1 -0
  34. package/dist/components/Slider/Slider.types.cjs +3 -0
  35. package/dist/components/Slider/Slider.types.cjs.map +1 -0
  36. package/dist/components/Slider/Slider.types.d.cts +135 -0
  37. package/dist/components/Slider/Slider.types.d.cts.map +1 -0
  38. package/dist/components/Slider/Slider.types.d.mts +135 -0
  39. package/dist/components/Slider/Slider.types.d.mts.map +1 -0
  40. package/dist/components/Slider/Slider.types.mjs +2 -0
  41. package/dist/components/Slider/Slider.types.mjs.map +1 -0
  42. package/dist/components/Slider/Slider.utilities.cjs +202 -0
  43. package/dist/components/Slider/Slider.utilities.cjs.map +1 -0
  44. package/dist/components/Slider/Slider.utilities.d.cts +108 -0
  45. package/dist/components/Slider/Slider.utilities.d.cts.map +1 -0
  46. package/dist/components/Slider/Slider.utilities.d.mts +108 -0
  47. package/dist/components/Slider/Slider.utilities.d.mts.map +1 -0
  48. package/dist/components/Slider/Slider.utilities.mjs +186 -0
  49. package/dist/components/Slider/Slider.utilities.mjs.map +1 -0
  50. package/dist/components/Slider/index.cjs +9 -0
  51. package/dist/components/Slider/index.cjs.map +1 -0
  52. package/dist/components/Slider/index.d.cts +4 -0
  53. package/dist/components/Slider/index.d.cts.map +1 -0
  54. package/dist/components/Slider/index.d.mts +4 -0
  55. package/dist/components/Slider/index.d.mts.map +1 -0
  56. package/dist/components/Slider/index.mjs +3 -0
  57. package/dist/components/Slider/index.mjs.map +1 -0
  58. package/dist/components/Slider/useSliderGesture.cjs +219 -0
  59. package/dist/components/Slider/useSliderGesture.cjs.map +1 -0
  60. package/dist/components/Slider/useSliderGesture.d.cts +17 -0
  61. package/dist/components/Slider/useSliderGesture.d.cts.map +1 -0
  62. package/dist/components/Slider/useSliderGesture.d.mts +17 -0
  63. package/dist/components/Slider/useSliderGesture.d.mts.map +1 -0
  64. package/dist/components/Slider/useSliderGesture.mjs +215 -0
  65. package/dist/components/Slider/useSliderGesture.mjs.map +1 -0
  66. package/dist/components/index.cjs +5 -1
  67. package/dist/components/index.cjs.map +1 -1
  68. package/dist/components/index.d.cts +2 -0
  69. package/dist/components/index.d.cts.map +1 -1
  70. package/dist/components/index.d.mts +2 -0
  71. package/dist/components/index.d.mts.map +1 -1
  72. package/dist/components/index.mjs +1 -0
  73. package/dist/components/index.mjs.map +1 -1
  74. package/package.json +2 -2
@@ -0,0 +1,139 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
15
+ }) : function(o, v) {
16
+ o["default"] = v;
17
+ });
18
+ var __importStar = (this && this.__importStar) || function (mod) {
19
+ if (mod && mod.__esModule) return mod;
20
+ var result = {};
21
+ if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
22
+ __setModuleDefault(result, mod);
23
+ return result;
24
+ };
25
+ var __importDefault = (this && this.__importDefault) || function (mod) {
26
+ return (mod && mod.__esModule) ? mod : { "default": mod };
27
+ };
28
+ Object.defineProperty(exports, "__esModule", { value: true });
29
+ exports.Slider = void 0;
30
+ const design_system_shared_1 = require("@metamask/design-system-shared");
31
+ const design_system_twrnc_preset_1 = require("@metamask/design-system-twrnc-preset");
32
+ const react_1 = __importStar(require("react"));
33
+ const react_native_1 = require("react-native");
34
+ const react_native_gesture_handler_1 = require("react-native-gesture-handler");
35
+ const react_native_reanimated_1 = __importDefault(require("react-native-reanimated"));
36
+ const Box_1 = require("../Box/index.cjs");
37
+ const Text_1 = require("../Text/index.cjs");
38
+ const Slider_constants_1 = require("./Slider.constants.cjs");
39
+ const Slider_utilities_1 = require("./Slider.utilities.cjs");
40
+ const useSliderGesture_1 = require("./useSliderGesture.cjs");
41
+ const Slider = ({ value, onValueChange, onDragEnd, minimumValue = 0, maximumValue = 100, step = 1, isDisabled = false, testID, rangeLabelSteps = Slider_constants_1.DEFAULT_RANGE_LABEL_STEPS, showRangeLabels = false, showRangeDots = false, onGrip, onTick, tickThresholds = Slider_constants_1.DEFAULT_TICK_THRESHOLDS, mapValueToTrackPercent, mapTrackPercentToValue, formatStepLabel, stepToValue: stepToValueProp, trackInset = Slider_constants_1.SLIDER_TRACK_INSET, twClassName, style, ...props }) => {
42
+ const tw = (0, design_system_twrnc_preset_1.useTailwind)();
43
+ const formatLabel = formatStepLabel ?? Slider_utilities_1.defaultFormatStepLabel;
44
+ const { handleLayout, progressStyle, thumbStyle, gesture, handlePressStep } = (0, useSliderGesture_1.useSliderGesture)({
45
+ value,
46
+ minimumValue,
47
+ maximumValue,
48
+ step,
49
+ isDisabled,
50
+ onValueChange,
51
+ onDragEnd,
52
+ onGrip,
53
+ onTick,
54
+ tickThresholds,
55
+ mapValueToTrackPercent,
56
+ mapTrackPercentToValue,
57
+ stepToValue: stepToValueProp,
58
+ });
59
+ const getAccessibilityText = (0, react_1.useCallback)(() => {
60
+ const trackPercent = Math.round((0, Slider_utilities_1.getTrackPercentFromValue)(value, minimumValue, maximumValue, mapValueToTrackPercent));
61
+ return `${trackPercent}%`;
62
+ }, [mapValueToTrackPercent, maximumValue, minimumValue, value]);
63
+ const handleAccessibilityAction = (0, react_1.useCallback)((event) => {
64
+ if (isDisabled) {
65
+ return;
66
+ }
67
+ const delta = event.nativeEvent.actionName === 'increment' ? step : -step;
68
+ const nextValue = (0, Slider_utilities_1.clampValueToRange)(value + delta, minimumValue, maximumValue, step);
69
+ if (nextValue !== value) {
70
+ onValueChange(nextValue);
71
+ onDragEnd?.(nextValue);
72
+ }
73
+ }, [
74
+ isDisabled,
75
+ maximumValue,
76
+ minimumValue,
77
+ onDragEnd,
78
+ onValueChange,
79
+ step,
80
+ value,
81
+ ]);
82
+ return (<Box_1.Box {...props} testID={testID} accessibilityRole="adjustable" accessibilityState={{ disabled: isDisabled }} accessibilityValue={{
83
+ min: minimumValue,
84
+ max: maximumValue,
85
+ now: value,
86
+ text: getAccessibilityText(),
87
+ }} accessibilityActions={[{ name: 'increment' }, { name: 'decrement' }]} onAccessibilityAction={handleAccessibilityAction} onLayout={handleLayout} style={[
88
+ tw.style('relative self-stretch', isDisabled ? 'py-2 opacity-40' : 'py-2'),
89
+ {
90
+ marginHorizontal: trackInset,
91
+ ...(showRangeLabels && { paddingBottom: Slider_constants_1.SLIDER_BOTTOM_PADDING }),
92
+ },
93
+ style,
94
+ ]} twClassName={twClassName}>
95
+ <react_native_gesture_handler_1.GestureDetector gesture={gesture}>
96
+ <react_native_reanimated_1.default.View style={[tw.style('relative'), { height: Slider_constants_1.THUMB_BOTTOM_OFFSET }]}>
97
+ <react_native_reanimated_1.default.View style={tw.style('absolute left-0 top-0 h-2 w-full rounded-full bg-border-muted')}/>
98
+ <react_native_reanimated_1.default.View style={[
99
+ tw.style('absolute left-0 top-0 h-2 rounded-full bg-icon-alternative'),
100
+ progressStyle,
101
+ ]}/>
102
+ {showRangeDots &&
103
+ rangeLabelSteps.map((rangeStep) => (<Box_1.Box key={`dot-${rangeStep}`} pointerEvents="none" twClassName="absolute top-0.5 h-1 w-1 rounded-full bg-text-muted" style={{
104
+ left: (0, Slider_utilities_1.getDotLeftPercent)(rangeStep),
105
+ transform: [{ translateX: -2 }],
106
+ zIndex: -2,
107
+ }}/>))}
108
+ <react_native_reanimated_1.default.View style={[
109
+ tw.style('absolute rounded-full bg-icon-default'),
110
+ {
111
+ width: Slider_constants_1.THUMB_SIZE,
112
+ height: Slider_constants_1.THUMB_SIZE,
113
+ top: Slider_constants_1.THUMB_TOP_OFFSET,
114
+ left: Slider_constants_1.THUMB_LEFT_OFFSET,
115
+ elevation: 4,
116
+ },
117
+ thumbStyle,
118
+ ]} hitSlop={{ top: 25, bottom: 25, left: 25, right: 25 }}/>
119
+ </react_native_reanimated_1.default.View>
120
+ </react_native_gesture_handler_1.GestureDetector>
121
+
122
+ {showRangeLabels &&
123
+ rangeLabelSteps.map((rangeStep) => (<react_native_1.Pressable key={`label-${rangeStep}`} style={[
124
+ tw.style('absolute items-center'),
125
+ {
126
+ top: Slider_constants_1.RANGE_LABEL_TOP,
127
+ left: (0, Slider_utilities_1.getDotLeftPercent)(rangeStep),
128
+ transform: [{ translateX: '-50%' }],
129
+ },
130
+ ]} onPress={() => handlePressStep(rangeStep)} disabled={isDisabled} accessibilityRole="button">
131
+ <Text_1.Text variant={design_system_shared_1.TextVariant.BodyMd} fontWeight={design_system_shared_1.FontWeight.Medium} color={design_system_shared_1.TextColor.TextAlternative}>
132
+ {formatLabel(rangeStep)}
133
+ </Text_1.Text>
134
+ </react_native_1.Pressable>))}
135
+ </Box_1.Box>);
136
+ };
137
+ exports.Slider = Slider;
138
+ exports.Slider.displayName = 'Slider';
139
+ //# sourceMappingURL=Slider.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Slider.cjs","sourceRoot":"","sources":["../../../src/components/Slider/Slider.tsx"],"names":[],"mappings":"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","sourcesContent":["import {\n FontWeight,\n TextColor,\n TextVariant,\n} from '@metamask/design-system-shared';\nimport { useTailwind } from '@metamask/design-system-twrnc-preset';\nimport React, { useCallback } from 'react';\nimport { AccessibilityActionEvent, Pressable } from 'react-native';\nimport type { ViewStyle } from 'react-native';\nimport { GestureDetector } from 'react-native-gesture-handler';\nimport Animated from 'react-native-reanimated';\n\nimport { Box } from '../Box';\nimport { Text } from '../Text';\n\nimport {\n DEFAULT_RANGE_LABEL_STEPS,\n DEFAULT_TICK_THRESHOLDS,\n RANGE_LABEL_TOP,\n SLIDER_BOTTOM_PADDING,\n SLIDER_TRACK_INSET,\n THUMB_BOTTOM_OFFSET,\n THUMB_LEFT_OFFSET,\n THUMB_SIZE,\n THUMB_TOP_OFFSET,\n} from './Slider.constants';\nimport type { SliderProps } from './Slider.types';\nimport {\n clampValueToRange,\n defaultFormatStepLabel,\n getDotLeftPercent,\n getTrackPercentFromValue,\n} from './Slider.utilities';\nimport { useSliderGesture } from './useSliderGesture';\n\nexport const Slider = ({\n value,\n onValueChange,\n onDragEnd,\n minimumValue = 0,\n maximumValue = 100,\n step = 1,\n isDisabled = false,\n testID,\n rangeLabelSteps = DEFAULT_RANGE_LABEL_STEPS,\n showRangeLabels = false,\n showRangeDots = false,\n onGrip,\n onTick,\n tickThresholds = DEFAULT_TICK_THRESHOLDS,\n mapValueToTrackPercent,\n mapTrackPercentToValue,\n formatStepLabel,\n stepToValue: stepToValueProp,\n trackInset = SLIDER_TRACK_INSET,\n twClassName,\n style,\n ...props\n}: SliderProps) => {\n const tw = useTailwind();\n\n const formatLabel = formatStepLabel ?? defaultFormatStepLabel;\n\n const { handleLayout, progressStyle, thumbStyle, gesture, handlePressStep } =\n useSliderGesture({\n value,\n minimumValue,\n maximumValue,\n step,\n isDisabled,\n onValueChange,\n onDragEnd,\n onGrip,\n onTick,\n tickThresholds,\n mapValueToTrackPercent,\n mapTrackPercentToValue,\n stepToValue: stepToValueProp,\n });\n\n const getAccessibilityText = useCallback(() => {\n const trackPercent = Math.round(\n getTrackPercentFromValue(\n value,\n minimumValue,\n maximumValue,\n mapValueToTrackPercent,\n ),\n );\n return `${trackPercent}%`;\n }, [mapValueToTrackPercent, maximumValue, minimumValue, value]);\n\n const handleAccessibilityAction = useCallback(\n (event: AccessibilityActionEvent) => {\n if (isDisabled) {\n return;\n }\n\n const delta = event.nativeEvent.actionName === 'increment' ? step : -step;\n const nextValue = clampValueToRange(\n value + delta,\n minimumValue,\n maximumValue,\n step,\n );\n\n if (nextValue !== value) {\n onValueChange(nextValue);\n onDragEnd?.(nextValue);\n }\n },\n [\n isDisabled,\n maximumValue,\n minimumValue,\n onDragEnd,\n onValueChange,\n step,\n value,\n ],\n );\n\n return (\n <Box\n {...props}\n testID={testID}\n accessibilityRole=\"adjustable\"\n accessibilityState={{ disabled: isDisabled }}\n accessibilityValue={{\n min: minimumValue,\n max: maximumValue,\n now: value,\n text: getAccessibilityText(),\n }}\n accessibilityActions={[{ name: 'increment' }, { name: 'decrement' }]}\n onAccessibilityAction={handleAccessibilityAction}\n onLayout={handleLayout}\n style={[\n tw.style(\n 'relative self-stretch',\n isDisabled ? 'py-2 opacity-40' : 'py-2',\n ),\n {\n marginHorizontal: trackInset,\n ...(showRangeLabels && { paddingBottom: SLIDER_BOTTOM_PADDING }),\n },\n style,\n ]}\n twClassName={twClassName}\n >\n <GestureDetector gesture={gesture}>\n <Animated.View\n style={[tw.style('relative'), { height: THUMB_BOTTOM_OFFSET }]}\n >\n <Animated.View\n style={tw.style(\n 'absolute left-0 top-0 h-2 w-full rounded-full bg-border-muted',\n )}\n />\n <Animated.View\n style={[\n tw.style(\n 'absolute left-0 top-0 h-2 rounded-full bg-icon-alternative',\n ),\n progressStyle,\n ]}\n />\n {showRangeDots &&\n rangeLabelSteps.map((rangeStep) => (\n <Box\n key={`dot-${rangeStep}`}\n pointerEvents=\"none\"\n twClassName=\"absolute top-0.5 h-1 w-1 rounded-full bg-text-muted\"\n style={{\n left: getDotLeftPercent(rangeStep) as ViewStyle['left'],\n transform: [{ translateX: -2 }],\n zIndex: -2,\n }}\n />\n ))}\n <Animated.View\n style={[\n tw.style('absolute rounded-full bg-icon-default'),\n {\n width: THUMB_SIZE,\n height: THUMB_SIZE,\n top: THUMB_TOP_OFFSET,\n left: THUMB_LEFT_OFFSET,\n elevation: 4,\n },\n thumbStyle,\n ]}\n hitSlop={{ top: 25, bottom: 25, left: 25, right: 25 }}\n />\n </Animated.View>\n </GestureDetector>\n\n {showRangeLabels &&\n rangeLabelSteps.map((rangeStep) => (\n <Pressable\n key={`label-${rangeStep}`}\n style={[\n tw.style('absolute items-center'),\n {\n top: RANGE_LABEL_TOP,\n left: getDotLeftPercent(rangeStep) as ViewStyle['left'],\n transform: [{ translateX: '-50%' }],\n },\n ]}\n onPress={() => handlePressStep(rangeStep)}\n disabled={isDisabled}\n accessibilityRole=\"button\"\n >\n <Text\n variant={TextVariant.BodyMd}\n fontWeight={FontWeight.Medium}\n color={TextColor.TextAlternative}\n >\n {formatLabel(rangeStep)}\n </Text>\n </Pressable>\n ))}\n </Box>\n );\n};\n\nSlider.displayName = 'Slider';\n"]}
@@ -0,0 +1,36 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.DEFAULT_TICK_THRESHOLDS = exports.DEFAULT_RANGE_LABEL_STEPS = exports.DOT_EDGE_MAX_PERCENT = exports.DOT_EDGE_INSET_PERCENT = exports.SLIDER_TRACK_INSET = exports.SLIDER_BOTTOM_PADDING = exports.SLIDER_LABEL_LINE_HEIGHT = exports.RANGE_LABEL_TOP = exports.SLIDER_VERTICAL_PADDING = exports.THUMB_GRIP_ANIMATION_DURATION = exports.THUMB_GRIP_SCALE = exports.THUMB_TO_LABEL_GAP = exports.THUMB_BOTTOM_OFFSET = exports.THUMB_LEFT_OFFSET = exports.THUMB_TOP_OFFSET = exports.THUMB_SIZE = void 0;
4
+ /** Slider geometry and behavior defaults — not typography or spacing tokens. */
5
+ exports.THUMB_SIZE = 32;
6
+ exports.THUMB_TOP_OFFSET = -13;
7
+ /** Negative offset so the thumb center aligns with the track start at 0%. */
8
+ exports.THUMB_LEFT_OFFSET = -16;
9
+ exports.THUMB_BOTTOM_OFFSET = exports.THUMB_TOP_OFFSET + exports.THUMB_SIZE;
10
+ exports.THUMB_TO_LABEL_GAP = 8;
11
+ /** Scale applied to the thumb while the user is dragging. */
12
+ exports.THUMB_GRIP_SCALE = 1.12;
13
+ /** Duration (ms) for thumb grip scale in/out. */
14
+ exports.THUMB_GRIP_ANIMATION_DURATION = 100;
15
+ /** Matches root `py-2` vertical padding on the slider container. */
16
+ exports.SLIDER_VERTICAL_PADDING = 8;
17
+ exports.RANGE_LABEL_TOP = exports.SLIDER_VERTICAL_PADDING + exports.THUMB_BOTTOM_OFFSET + exports.THUMB_TO_LABEL_GAP;
18
+ /** Approximate line height for BodyMd range labels below the track. */
19
+ exports.SLIDER_LABEL_LINE_HEIGHT = 20;
20
+ /** Bottom padding when range labels may render (RANGE_LABEL_TOP + label height). */
21
+ exports.SLIDER_BOTTOM_PADDING = exports.RANGE_LABEL_TOP + exports.SLIDER_LABEL_LINE_HEIGHT;
22
+ /**
23
+ * Default horizontal inset on the root container; equals |THUMB_LEFT_OFFSET| so
24
+ * the thumb can overhang at min/max without clipping.
25
+ */
26
+ exports.SLIDER_TRACK_INSET = Math.abs(exports.THUMB_LEFT_OFFSET);
27
+ /**
28
+ * Edge marker inset (percent) so dots/labels at 0/100 stay on the visible track.
29
+ * The thumb at 0% sits half its width (THUMB_SIZE / 2) left of the track start;
30
+ * a small inset keeps edge markers from sitting under the thumb center.
31
+ */
32
+ exports.DOT_EDGE_INSET_PERCENT = '2%';
33
+ exports.DOT_EDGE_MAX_PERCENT = '98%';
34
+ exports.DEFAULT_RANGE_LABEL_STEPS = [0, 25, 50, 75, 100];
35
+ exports.DEFAULT_TICK_THRESHOLDS = [25, 50, 75];
36
+ //# sourceMappingURL=Slider.constants.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Slider.constants.cjs","sourceRoot":"","sources":["../../../src/components/Slider/Slider.constants.ts"],"names":[],"mappings":";;;AAAA,gFAAgF;AACnE,QAAA,UAAU,GAAG,EAAE,CAAC;AAChB,QAAA,gBAAgB,GAAG,CAAC,EAAE,CAAC;AACpC,6EAA6E;AAChE,QAAA,iBAAiB,GAAG,CAAC,EAAE,CAAC;AACxB,QAAA,mBAAmB,GAAG,wBAAgB,GAAG,kBAAU,CAAC;AACpD,QAAA,kBAAkB,GAAG,CAAC,CAAC;AACpC,6DAA6D;AAChD,QAAA,gBAAgB,GAAG,IAAI,CAAC;AACrC,iDAAiD;AACpC,QAAA,6BAA6B,GAAG,GAAG,CAAC;AACjD,oEAAoE;AACvD,QAAA,uBAAuB,GAAG,CAAC,CAAC;AAC5B,QAAA,eAAe,GAC1B,+BAAuB,GAAG,2BAAmB,GAAG,0BAAkB,CAAC;AACrE,uEAAuE;AAC1D,QAAA,wBAAwB,GAAG,EAAE,CAAC;AAC3C,oFAAoF;AACvE,QAAA,qBAAqB,GAAG,uBAAe,GAAG,gCAAwB,CAAC;AAChF;;;GAGG;AACU,QAAA,kBAAkB,GAAG,IAAI,CAAC,GAAG,CAAC,yBAAiB,CAAC,CAAC;AAC9D;;;;GAIG;AACU,QAAA,sBAAsB,GAAG,IAAI,CAAC;AAC9B,QAAA,oBAAoB,GAAG,KAAK,CAAC;AAE7B,QAAA,yBAAyB,GAAG,CAAC,CAAC,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,GAAG,CAAU,CAAC;AAC1D,QAAA,uBAAuB,GAAG,CAAC,EAAE,EAAE,EAAE,EAAE,EAAE,CAAU,CAAC","sourcesContent":["/** Slider geometry and behavior defaults — not typography or spacing tokens. */\nexport const THUMB_SIZE = 32;\nexport const THUMB_TOP_OFFSET = -13;\n/** Negative offset so the thumb center aligns with the track start at 0%. */\nexport const THUMB_LEFT_OFFSET = -16;\nexport const THUMB_BOTTOM_OFFSET = THUMB_TOP_OFFSET + THUMB_SIZE;\nexport const THUMB_TO_LABEL_GAP = 8;\n/** Scale applied to the thumb while the user is dragging. */\nexport const THUMB_GRIP_SCALE = 1.12;\n/** Duration (ms) for thumb grip scale in/out. */\nexport const THUMB_GRIP_ANIMATION_DURATION = 100;\n/** Matches root `py-2` vertical padding on the slider container. */\nexport const SLIDER_VERTICAL_PADDING = 8;\nexport const RANGE_LABEL_TOP =\n SLIDER_VERTICAL_PADDING + THUMB_BOTTOM_OFFSET + THUMB_TO_LABEL_GAP;\n/** Approximate line height for BodyMd range labels below the track. */\nexport const SLIDER_LABEL_LINE_HEIGHT = 20;\n/** Bottom padding when range labels may render (RANGE_LABEL_TOP + label height). */\nexport const SLIDER_BOTTOM_PADDING = RANGE_LABEL_TOP + SLIDER_LABEL_LINE_HEIGHT;\n/**\n * Default horizontal inset on the root container; equals |THUMB_LEFT_OFFSET| so\n * the thumb can overhang at min/max without clipping.\n */\nexport const SLIDER_TRACK_INSET = Math.abs(THUMB_LEFT_OFFSET);\n/**\n * Edge marker inset (percent) so dots/labels at 0/100 stay on the visible track.\n * The thumb at 0% sits half its width (THUMB_SIZE / 2) left of the track start;\n * a small inset keeps edge markers from sitting under the thumb center.\n */\nexport const DOT_EDGE_INSET_PERCENT = '2%';\nexport const DOT_EDGE_MAX_PERCENT = '98%';\n\nexport const DEFAULT_RANGE_LABEL_STEPS = [0, 25, 50, 75, 100] as const;\nexport const DEFAULT_TICK_THRESHOLDS = [25, 50, 75] as const;\n"]}
@@ -0,0 +1,33 @@
1
+ /** Slider geometry and behavior defaults — not typography or spacing tokens. */
2
+ export declare const THUMB_SIZE = 32;
3
+ export declare const THUMB_TOP_OFFSET = -13;
4
+ /** Negative offset so the thumb center aligns with the track start at 0%. */
5
+ export declare const THUMB_LEFT_OFFSET = -16;
6
+ export declare const THUMB_BOTTOM_OFFSET: number;
7
+ export declare const THUMB_TO_LABEL_GAP = 8;
8
+ /** Scale applied to the thumb while the user is dragging. */
9
+ export declare const THUMB_GRIP_SCALE = 1.12;
10
+ /** Duration (ms) for thumb grip scale in/out. */
11
+ export declare const THUMB_GRIP_ANIMATION_DURATION = 100;
12
+ /** Matches root `py-2` vertical padding on the slider container. */
13
+ export declare const SLIDER_VERTICAL_PADDING = 8;
14
+ export declare const RANGE_LABEL_TOP: number;
15
+ /** Approximate line height for BodyMd range labels below the track. */
16
+ export declare const SLIDER_LABEL_LINE_HEIGHT = 20;
17
+ /** Bottom padding when range labels may render (RANGE_LABEL_TOP + label height). */
18
+ export declare const SLIDER_BOTTOM_PADDING: number;
19
+ /**
20
+ * Default horizontal inset on the root container; equals |THUMB_LEFT_OFFSET| so
21
+ * the thumb can overhang at min/max without clipping.
22
+ */
23
+ export declare const SLIDER_TRACK_INSET: number;
24
+ /**
25
+ * Edge marker inset (percent) so dots/labels at 0/100 stay on the visible track.
26
+ * The thumb at 0% sits half its width (THUMB_SIZE / 2) left of the track start;
27
+ * a small inset keeps edge markers from sitting under the thumb center.
28
+ */
29
+ export declare const DOT_EDGE_INSET_PERCENT = "2%";
30
+ export declare const DOT_EDGE_MAX_PERCENT = "98%";
31
+ export declare const DEFAULT_RANGE_LABEL_STEPS: readonly [0, 25, 50, 75, 100];
32
+ export declare const DEFAULT_TICK_THRESHOLDS: readonly [25, 50, 75];
33
+ //# sourceMappingURL=Slider.constants.d.cts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Slider.constants.d.cts","sourceRoot":"","sources":["../../../src/components/Slider/Slider.constants.ts"],"names":[],"mappings":"AAAA,gFAAgF;AAChF,eAAO,MAAM,UAAU,KAAK,CAAC;AAC7B,eAAO,MAAM,gBAAgB,MAAM,CAAC;AACpC,6EAA6E;AAC7E,eAAO,MAAM,iBAAiB,MAAM,CAAC;AACrC,eAAO,MAAM,mBAAmB,QAAgC,CAAC;AACjE,eAAO,MAAM,kBAAkB,IAAI,CAAC;AACpC,6DAA6D;AAC7D,eAAO,MAAM,gBAAgB,OAAO,CAAC;AACrC,iDAAiD;AACjD,eAAO,MAAM,6BAA6B,MAAM,CAAC;AACjD,oEAAoE;AACpE,eAAO,MAAM,uBAAuB,IAAI,CAAC;AACzC,eAAO,MAAM,eAAe,QACwC,CAAC;AACrE,uEAAuE;AACvE,eAAO,MAAM,wBAAwB,KAAK,CAAC;AAC3C,oFAAoF;AACpF,eAAO,MAAM,qBAAqB,QAA6C,CAAC;AAChF;;;GAGG;AACH,eAAO,MAAM,kBAAkB,QAA8B,CAAC;AAC9D;;;;GAIG;AACH,eAAO,MAAM,sBAAsB,OAAO,CAAC;AAC3C,eAAO,MAAM,oBAAoB,QAAQ,CAAC;AAE1C,eAAO,MAAM,yBAAyB,+BAAgC,CAAC;AACvE,eAAO,MAAM,uBAAuB,uBAAwB,CAAC"}
@@ -0,0 +1,33 @@
1
+ /** Slider geometry and behavior defaults — not typography or spacing tokens. */
2
+ export declare const THUMB_SIZE = 32;
3
+ export declare const THUMB_TOP_OFFSET = -13;
4
+ /** Negative offset so the thumb center aligns with the track start at 0%. */
5
+ export declare const THUMB_LEFT_OFFSET = -16;
6
+ export declare const THUMB_BOTTOM_OFFSET: number;
7
+ export declare const THUMB_TO_LABEL_GAP = 8;
8
+ /** Scale applied to the thumb while the user is dragging. */
9
+ export declare const THUMB_GRIP_SCALE = 1.12;
10
+ /** Duration (ms) for thumb grip scale in/out. */
11
+ export declare const THUMB_GRIP_ANIMATION_DURATION = 100;
12
+ /** Matches root `py-2` vertical padding on the slider container. */
13
+ export declare const SLIDER_VERTICAL_PADDING = 8;
14
+ export declare const RANGE_LABEL_TOP: number;
15
+ /** Approximate line height for BodyMd range labels below the track. */
16
+ export declare const SLIDER_LABEL_LINE_HEIGHT = 20;
17
+ /** Bottom padding when range labels may render (RANGE_LABEL_TOP + label height). */
18
+ export declare const SLIDER_BOTTOM_PADDING: number;
19
+ /**
20
+ * Default horizontal inset on the root container; equals |THUMB_LEFT_OFFSET| so
21
+ * the thumb can overhang at min/max without clipping.
22
+ */
23
+ export declare const SLIDER_TRACK_INSET: number;
24
+ /**
25
+ * Edge marker inset (percent) so dots/labels at 0/100 stay on the visible track.
26
+ * The thumb at 0% sits half its width (THUMB_SIZE / 2) left of the track start;
27
+ * a small inset keeps edge markers from sitting under the thumb center.
28
+ */
29
+ export declare const DOT_EDGE_INSET_PERCENT = "2%";
30
+ export declare const DOT_EDGE_MAX_PERCENT = "98%";
31
+ export declare const DEFAULT_RANGE_LABEL_STEPS: readonly [0, 25, 50, 75, 100];
32
+ export declare const DEFAULT_TICK_THRESHOLDS: readonly [25, 50, 75];
33
+ //# sourceMappingURL=Slider.constants.d.mts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Slider.constants.d.mts","sourceRoot":"","sources":["../../../src/components/Slider/Slider.constants.ts"],"names":[],"mappings":"AAAA,gFAAgF;AAChF,eAAO,MAAM,UAAU,KAAK,CAAC;AAC7B,eAAO,MAAM,gBAAgB,MAAM,CAAC;AACpC,6EAA6E;AAC7E,eAAO,MAAM,iBAAiB,MAAM,CAAC;AACrC,eAAO,MAAM,mBAAmB,QAAgC,CAAC;AACjE,eAAO,MAAM,kBAAkB,IAAI,CAAC;AACpC,6DAA6D;AAC7D,eAAO,MAAM,gBAAgB,OAAO,CAAC;AACrC,iDAAiD;AACjD,eAAO,MAAM,6BAA6B,MAAM,CAAC;AACjD,oEAAoE;AACpE,eAAO,MAAM,uBAAuB,IAAI,CAAC;AACzC,eAAO,MAAM,eAAe,QACwC,CAAC;AACrE,uEAAuE;AACvE,eAAO,MAAM,wBAAwB,KAAK,CAAC;AAC3C,oFAAoF;AACpF,eAAO,MAAM,qBAAqB,QAA6C,CAAC;AAChF;;;GAGG;AACH,eAAO,MAAM,kBAAkB,QAA8B,CAAC;AAC9D;;;;GAIG;AACH,eAAO,MAAM,sBAAsB,OAAO,CAAC;AAC3C,eAAO,MAAM,oBAAoB,QAAQ,CAAC;AAE1C,eAAO,MAAM,yBAAyB,+BAAgC,CAAC;AACvE,eAAO,MAAM,uBAAuB,uBAAwB,CAAC"}
@@ -0,0 +1,33 @@
1
+ /** Slider geometry and behavior defaults — not typography or spacing tokens. */
2
+ export const THUMB_SIZE = 32;
3
+ export const THUMB_TOP_OFFSET = -13;
4
+ /** Negative offset so the thumb center aligns with the track start at 0%. */
5
+ export const THUMB_LEFT_OFFSET = -16;
6
+ export const THUMB_BOTTOM_OFFSET = THUMB_TOP_OFFSET + THUMB_SIZE;
7
+ export const THUMB_TO_LABEL_GAP = 8;
8
+ /** Scale applied to the thumb while the user is dragging. */
9
+ export const THUMB_GRIP_SCALE = 1.12;
10
+ /** Duration (ms) for thumb grip scale in/out. */
11
+ export const THUMB_GRIP_ANIMATION_DURATION = 100;
12
+ /** Matches root `py-2` vertical padding on the slider container. */
13
+ export const SLIDER_VERTICAL_PADDING = 8;
14
+ export const RANGE_LABEL_TOP = SLIDER_VERTICAL_PADDING + THUMB_BOTTOM_OFFSET + THUMB_TO_LABEL_GAP;
15
+ /** Approximate line height for BodyMd range labels below the track. */
16
+ export const SLIDER_LABEL_LINE_HEIGHT = 20;
17
+ /** Bottom padding when range labels may render (RANGE_LABEL_TOP + label height). */
18
+ export const SLIDER_BOTTOM_PADDING = RANGE_LABEL_TOP + SLIDER_LABEL_LINE_HEIGHT;
19
+ /**
20
+ * Default horizontal inset on the root container; equals |THUMB_LEFT_OFFSET| so
21
+ * the thumb can overhang at min/max without clipping.
22
+ */
23
+ export const SLIDER_TRACK_INSET = Math.abs(THUMB_LEFT_OFFSET);
24
+ /**
25
+ * Edge marker inset (percent) so dots/labels at 0/100 stay on the visible track.
26
+ * The thumb at 0% sits half its width (THUMB_SIZE / 2) left of the track start;
27
+ * a small inset keeps edge markers from sitting under the thumb center.
28
+ */
29
+ export const DOT_EDGE_INSET_PERCENT = '2%';
30
+ export const DOT_EDGE_MAX_PERCENT = '98%';
31
+ export const DEFAULT_RANGE_LABEL_STEPS = [0, 25, 50, 75, 100];
32
+ export const DEFAULT_TICK_THRESHOLDS = [25, 50, 75];
33
+ //# sourceMappingURL=Slider.constants.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Slider.constants.mjs","sourceRoot":"","sources":["../../../src/components/Slider/Slider.constants.ts"],"names":[],"mappings":"AAAA,gFAAgF;AAChF,MAAM,CAAC,MAAM,UAAU,GAAG,EAAE,CAAC;AAC7B,MAAM,CAAC,MAAM,gBAAgB,GAAG,CAAC,EAAE,CAAC;AACpC,6EAA6E;AAC7E,MAAM,CAAC,MAAM,iBAAiB,GAAG,CAAC,EAAE,CAAC;AACrC,MAAM,CAAC,MAAM,mBAAmB,GAAG,gBAAgB,GAAG,UAAU,CAAC;AACjE,MAAM,CAAC,MAAM,kBAAkB,GAAG,CAAC,CAAC;AACpC,6DAA6D;AAC7D,MAAM,CAAC,MAAM,gBAAgB,GAAG,IAAI,CAAC;AACrC,iDAAiD;AACjD,MAAM,CAAC,MAAM,6BAA6B,GAAG,GAAG,CAAC;AACjD,oEAAoE;AACpE,MAAM,CAAC,MAAM,uBAAuB,GAAG,CAAC,CAAC;AACzC,MAAM,CAAC,MAAM,eAAe,GAC1B,uBAAuB,GAAG,mBAAmB,GAAG,kBAAkB,CAAC;AACrE,uEAAuE;AACvE,MAAM,CAAC,MAAM,wBAAwB,GAAG,EAAE,CAAC;AAC3C,oFAAoF;AACpF,MAAM,CAAC,MAAM,qBAAqB,GAAG,eAAe,GAAG,wBAAwB,CAAC;AAChF;;;GAGG;AACH,MAAM,CAAC,MAAM,kBAAkB,GAAG,IAAI,CAAC,GAAG,CAAC,iBAAiB,CAAC,CAAC;AAC9D;;;;GAIG;AACH,MAAM,CAAC,MAAM,sBAAsB,GAAG,IAAI,CAAC;AAC3C,MAAM,CAAC,MAAM,oBAAoB,GAAG,KAAK,CAAC;AAE1C,MAAM,CAAC,MAAM,yBAAyB,GAAG,CAAC,CAAC,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,GAAG,CAAU,CAAC;AACvE,MAAM,CAAC,MAAM,uBAAuB,GAAG,CAAC,EAAE,EAAE,EAAE,EAAE,EAAE,CAAU,CAAC","sourcesContent":["/** Slider geometry and behavior defaults — not typography or spacing tokens. */\nexport const THUMB_SIZE = 32;\nexport const THUMB_TOP_OFFSET = -13;\n/** Negative offset so the thumb center aligns with the track start at 0%. */\nexport const THUMB_LEFT_OFFSET = -16;\nexport const THUMB_BOTTOM_OFFSET = THUMB_TOP_OFFSET + THUMB_SIZE;\nexport const THUMB_TO_LABEL_GAP = 8;\n/** Scale applied to the thumb while the user is dragging. */\nexport const THUMB_GRIP_SCALE = 1.12;\n/** Duration (ms) for thumb grip scale in/out. */\nexport const THUMB_GRIP_ANIMATION_DURATION = 100;\n/** Matches root `py-2` vertical padding on the slider container. */\nexport const SLIDER_VERTICAL_PADDING = 8;\nexport const RANGE_LABEL_TOP =\n SLIDER_VERTICAL_PADDING + THUMB_BOTTOM_OFFSET + THUMB_TO_LABEL_GAP;\n/** Approximate line height for BodyMd range labels below the track. */\nexport const SLIDER_LABEL_LINE_HEIGHT = 20;\n/** Bottom padding when range labels may render (RANGE_LABEL_TOP + label height). */\nexport const SLIDER_BOTTOM_PADDING = RANGE_LABEL_TOP + SLIDER_LABEL_LINE_HEIGHT;\n/**\n * Default horizontal inset on the root container; equals |THUMB_LEFT_OFFSET| so\n * the thumb can overhang at min/max without clipping.\n */\nexport const SLIDER_TRACK_INSET = Math.abs(THUMB_LEFT_OFFSET);\n/**\n * Edge marker inset (percent) so dots/labels at 0/100 stay on the visible track.\n * The thumb at 0% sits half its width (THUMB_SIZE / 2) left of the track start;\n * a small inset keeps edge markers from sitting under the thumb center.\n */\nexport const DOT_EDGE_INSET_PERCENT = '2%';\nexport const DOT_EDGE_MAX_PERCENT = '98%';\n\nexport const DEFAULT_RANGE_LABEL_STEPS = [0, 25, 50, 75, 100] as const;\nexport const DEFAULT_TICK_THRESHOLDS = [25, 50, 75] as const;\n"]}
@@ -0,0 +1,7 @@
1
+ import React from "react";
2
+ import type { SliderProps } from "./Slider.types.cjs";
3
+ export declare const Slider: {
4
+ ({ value, onValueChange, onDragEnd, minimumValue, maximumValue, step, isDisabled, testID, rangeLabelSteps, showRangeLabels, showRangeDots, onGrip, onTick, tickThresholds, mapValueToTrackPercent, mapTrackPercentToValue, formatStepLabel, stepToValue: stepToValueProp, trackInset, twClassName, style, ...props }: SliderProps): React.JSX.Element;
5
+ displayName: string;
6
+ };
7
+ //# sourceMappingURL=Slider.d.cts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Slider.d.cts","sourceRoot":"","sources":["../../../src/components/Slider/Slider.tsx"],"names":[],"mappings":"AAMA,OAAO,KAAsB,cAAc;AAoB3C,OAAO,KAAK,EAAE,WAAW,EAAE,2BAAuB;AASlD,eAAO,MAAM,MAAM;0TAuBhB,WAAW;;CAsKb,CAAC"}
@@ -0,0 +1,7 @@
1
+ import React from "react";
2
+ import type { SliderProps } from "./Slider.types.mjs";
3
+ export declare const Slider: {
4
+ ({ value, onValueChange, onDragEnd, minimumValue, maximumValue, step, isDisabled, testID, rangeLabelSteps, showRangeLabels, showRangeDots, onGrip, onTick, tickThresholds, mapValueToTrackPercent, mapTrackPercentToValue, formatStepLabel, stepToValue: stepToValueProp, trackInset, twClassName, style, ...props }: SliderProps): React.JSX.Element;
5
+ displayName: string;
6
+ };
7
+ //# sourceMappingURL=Slider.d.mts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Slider.d.mts","sourceRoot":"","sources":["../../../src/components/Slider/Slider.tsx"],"names":[],"mappings":"AAMA,OAAO,KAAsB,cAAc;AAoB3C,OAAO,KAAK,EAAE,WAAW,EAAE,2BAAuB;AASlD,eAAO,MAAM,MAAM;0TAuBhB,WAAW;;CAsKb,CAAC"}
@@ -0,0 +1,116 @@
1
+ function $importDefault(module) {
2
+ if (module?.__esModule) {
3
+ return module.default;
4
+ }
5
+ return module;
6
+ }
7
+ import { FontWeight, TextColor, TextVariant } from "@metamask/design-system-shared";
8
+ import { useTailwind } from "@metamask/design-system-twrnc-preset";
9
+ import $React, { useCallback } from "react";
10
+ const React = $importDefault($React);
11
+ import { Pressable } from "react-native";
12
+ import { GestureDetector } from "react-native-gesture-handler";
13
+ import Animated from "react-native-reanimated";
14
+ import { Box } from "../Box/index.mjs";
15
+ import { Text } from "../Text/index.mjs";
16
+ import { DEFAULT_RANGE_LABEL_STEPS, DEFAULT_TICK_THRESHOLDS, RANGE_LABEL_TOP, SLIDER_BOTTOM_PADDING, SLIDER_TRACK_INSET, THUMB_BOTTOM_OFFSET, THUMB_LEFT_OFFSET, THUMB_SIZE, THUMB_TOP_OFFSET } from "./Slider.constants.mjs";
17
+ import { clampValueToRange, defaultFormatStepLabel, getDotLeftPercent, getTrackPercentFromValue } from "./Slider.utilities.mjs";
18
+ import { useSliderGesture } from "./useSliderGesture.mjs";
19
+ export const Slider = ({ value, onValueChange, onDragEnd, minimumValue = 0, maximumValue = 100, step = 1, isDisabled = false, testID, rangeLabelSteps = DEFAULT_RANGE_LABEL_STEPS, showRangeLabels = false, showRangeDots = false, onGrip, onTick, tickThresholds = DEFAULT_TICK_THRESHOLDS, mapValueToTrackPercent, mapTrackPercentToValue, formatStepLabel, stepToValue: stepToValueProp, trackInset = SLIDER_TRACK_INSET, twClassName, style, ...props }) => {
20
+ const tw = useTailwind();
21
+ const formatLabel = formatStepLabel ?? defaultFormatStepLabel;
22
+ const { handleLayout, progressStyle, thumbStyle, gesture, handlePressStep } = useSliderGesture({
23
+ value,
24
+ minimumValue,
25
+ maximumValue,
26
+ step,
27
+ isDisabled,
28
+ onValueChange,
29
+ onDragEnd,
30
+ onGrip,
31
+ onTick,
32
+ tickThresholds,
33
+ mapValueToTrackPercent,
34
+ mapTrackPercentToValue,
35
+ stepToValue: stepToValueProp,
36
+ });
37
+ const getAccessibilityText = useCallback(() => {
38
+ const trackPercent = Math.round(getTrackPercentFromValue(value, minimumValue, maximumValue, mapValueToTrackPercent));
39
+ return `${trackPercent}%`;
40
+ }, [mapValueToTrackPercent, maximumValue, minimumValue, value]);
41
+ const handleAccessibilityAction = useCallback((event) => {
42
+ if (isDisabled) {
43
+ return;
44
+ }
45
+ const delta = event.nativeEvent.actionName === 'increment' ? step : -step;
46
+ const nextValue = clampValueToRange(value + delta, minimumValue, maximumValue, step);
47
+ if (nextValue !== value) {
48
+ onValueChange(nextValue);
49
+ onDragEnd?.(nextValue);
50
+ }
51
+ }, [
52
+ isDisabled,
53
+ maximumValue,
54
+ minimumValue,
55
+ onDragEnd,
56
+ onValueChange,
57
+ step,
58
+ value,
59
+ ]);
60
+ return (<Box {...props} testID={testID} accessibilityRole="adjustable" accessibilityState={{ disabled: isDisabled }} accessibilityValue={{
61
+ min: minimumValue,
62
+ max: maximumValue,
63
+ now: value,
64
+ text: getAccessibilityText(),
65
+ }} accessibilityActions={[{ name: 'increment' }, { name: 'decrement' }]} onAccessibilityAction={handleAccessibilityAction} onLayout={handleLayout} style={[
66
+ tw.style('relative self-stretch', isDisabled ? 'py-2 opacity-40' : 'py-2'),
67
+ {
68
+ marginHorizontal: trackInset,
69
+ ...(showRangeLabels && { paddingBottom: SLIDER_BOTTOM_PADDING }),
70
+ },
71
+ style,
72
+ ]} twClassName={twClassName}>
73
+ <GestureDetector gesture={gesture}>
74
+ <Animated.View style={[tw.style('relative'), { height: THUMB_BOTTOM_OFFSET }]}>
75
+ <Animated.View style={tw.style('absolute left-0 top-0 h-2 w-full rounded-full bg-border-muted')}/>
76
+ <Animated.View style={[
77
+ tw.style('absolute left-0 top-0 h-2 rounded-full bg-icon-alternative'),
78
+ progressStyle,
79
+ ]}/>
80
+ {showRangeDots &&
81
+ rangeLabelSteps.map((rangeStep) => (<Box key={`dot-${rangeStep}`} pointerEvents="none" twClassName="absolute top-0.5 h-1 w-1 rounded-full bg-text-muted" style={{
82
+ left: getDotLeftPercent(rangeStep),
83
+ transform: [{ translateX: -2 }],
84
+ zIndex: -2,
85
+ }}/>))}
86
+ <Animated.View style={[
87
+ tw.style('absolute rounded-full bg-icon-default'),
88
+ {
89
+ width: THUMB_SIZE,
90
+ height: THUMB_SIZE,
91
+ top: THUMB_TOP_OFFSET,
92
+ left: THUMB_LEFT_OFFSET,
93
+ elevation: 4,
94
+ },
95
+ thumbStyle,
96
+ ]} hitSlop={{ top: 25, bottom: 25, left: 25, right: 25 }}/>
97
+ </Animated.View>
98
+ </GestureDetector>
99
+
100
+ {showRangeLabels &&
101
+ rangeLabelSteps.map((rangeStep) => (<Pressable key={`label-${rangeStep}`} style={[
102
+ tw.style('absolute items-center'),
103
+ {
104
+ top: RANGE_LABEL_TOP,
105
+ left: getDotLeftPercent(rangeStep),
106
+ transform: [{ translateX: '-50%' }],
107
+ },
108
+ ]} onPress={() => handlePressStep(rangeStep)} disabled={isDisabled} accessibilityRole="button">
109
+ <Text variant={TextVariant.BodyMd} fontWeight={FontWeight.Medium} color={TextColor.TextAlternative}>
110
+ {formatLabel(rangeStep)}
111
+ </Text>
112
+ </Pressable>))}
113
+ </Box>);
114
+ };
115
+ Slider.displayName = 'Slider';
116
+ //# sourceMappingURL=Slider.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Slider.mjs","sourceRoot":"","sources":["../../../src/components/Slider/Slider.tsx"],"names":[],"mappings":"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","sourcesContent":["import {\n FontWeight,\n TextColor,\n TextVariant,\n} from '@metamask/design-system-shared';\nimport { useTailwind } from '@metamask/design-system-twrnc-preset';\nimport React, { useCallback } from 'react';\nimport { AccessibilityActionEvent, Pressable } from 'react-native';\nimport type { ViewStyle } from 'react-native';\nimport { GestureDetector } from 'react-native-gesture-handler';\nimport Animated from 'react-native-reanimated';\n\nimport { Box } from '../Box';\nimport { Text } from '../Text';\n\nimport {\n DEFAULT_RANGE_LABEL_STEPS,\n DEFAULT_TICK_THRESHOLDS,\n RANGE_LABEL_TOP,\n SLIDER_BOTTOM_PADDING,\n SLIDER_TRACK_INSET,\n THUMB_BOTTOM_OFFSET,\n THUMB_LEFT_OFFSET,\n THUMB_SIZE,\n THUMB_TOP_OFFSET,\n} from './Slider.constants';\nimport type { SliderProps } from './Slider.types';\nimport {\n clampValueToRange,\n defaultFormatStepLabel,\n getDotLeftPercent,\n getTrackPercentFromValue,\n} from './Slider.utilities';\nimport { useSliderGesture } from './useSliderGesture';\n\nexport const Slider = ({\n value,\n onValueChange,\n onDragEnd,\n minimumValue = 0,\n maximumValue = 100,\n step = 1,\n isDisabled = false,\n testID,\n rangeLabelSteps = DEFAULT_RANGE_LABEL_STEPS,\n showRangeLabels = false,\n showRangeDots = false,\n onGrip,\n onTick,\n tickThresholds = DEFAULT_TICK_THRESHOLDS,\n mapValueToTrackPercent,\n mapTrackPercentToValue,\n formatStepLabel,\n stepToValue: stepToValueProp,\n trackInset = SLIDER_TRACK_INSET,\n twClassName,\n style,\n ...props\n}: SliderProps) => {\n const tw = useTailwind();\n\n const formatLabel = formatStepLabel ?? defaultFormatStepLabel;\n\n const { handleLayout, progressStyle, thumbStyle, gesture, handlePressStep } =\n useSliderGesture({\n value,\n minimumValue,\n maximumValue,\n step,\n isDisabled,\n onValueChange,\n onDragEnd,\n onGrip,\n onTick,\n tickThresholds,\n mapValueToTrackPercent,\n mapTrackPercentToValue,\n stepToValue: stepToValueProp,\n });\n\n const getAccessibilityText = useCallback(() => {\n const trackPercent = Math.round(\n getTrackPercentFromValue(\n value,\n minimumValue,\n maximumValue,\n mapValueToTrackPercent,\n ),\n );\n return `${trackPercent}%`;\n }, [mapValueToTrackPercent, maximumValue, minimumValue, value]);\n\n const handleAccessibilityAction = useCallback(\n (event: AccessibilityActionEvent) => {\n if (isDisabled) {\n return;\n }\n\n const delta = event.nativeEvent.actionName === 'increment' ? step : -step;\n const nextValue = clampValueToRange(\n value + delta,\n minimumValue,\n maximumValue,\n step,\n );\n\n if (nextValue !== value) {\n onValueChange(nextValue);\n onDragEnd?.(nextValue);\n }\n },\n [\n isDisabled,\n maximumValue,\n minimumValue,\n onDragEnd,\n onValueChange,\n step,\n value,\n ],\n );\n\n return (\n <Box\n {...props}\n testID={testID}\n accessibilityRole=\"adjustable\"\n accessibilityState={{ disabled: isDisabled }}\n accessibilityValue={{\n min: minimumValue,\n max: maximumValue,\n now: value,\n text: getAccessibilityText(),\n }}\n accessibilityActions={[{ name: 'increment' }, { name: 'decrement' }]}\n onAccessibilityAction={handleAccessibilityAction}\n onLayout={handleLayout}\n style={[\n tw.style(\n 'relative self-stretch',\n isDisabled ? 'py-2 opacity-40' : 'py-2',\n ),\n {\n marginHorizontal: trackInset,\n ...(showRangeLabels && { paddingBottom: SLIDER_BOTTOM_PADDING }),\n },\n style,\n ]}\n twClassName={twClassName}\n >\n <GestureDetector gesture={gesture}>\n <Animated.View\n style={[tw.style('relative'), { height: THUMB_BOTTOM_OFFSET }]}\n >\n <Animated.View\n style={tw.style(\n 'absolute left-0 top-0 h-2 w-full rounded-full bg-border-muted',\n )}\n />\n <Animated.View\n style={[\n tw.style(\n 'absolute left-0 top-0 h-2 rounded-full bg-icon-alternative',\n ),\n progressStyle,\n ]}\n />\n {showRangeDots &&\n rangeLabelSteps.map((rangeStep) => (\n <Box\n key={`dot-${rangeStep}`}\n pointerEvents=\"none\"\n twClassName=\"absolute top-0.5 h-1 w-1 rounded-full bg-text-muted\"\n style={{\n left: getDotLeftPercent(rangeStep) as ViewStyle['left'],\n transform: [{ translateX: -2 }],\n zIndex: -2,\n }}\n />\n ))}\n <Animated.View\n style={[\n tw.style('absolute rounded-full bg-icon-default'),\n {\n width: THUMB_SIZE,\n height: THUMB_SIZE,\n top: THUMB_TOP_OFFSET,\n left: THUMB_LEFT_OFFSET,\n elevation: 4,\n },\n thumbStyle,\n ]}\n hitSlop={{ top: 25, bottom: 25, left: 25, right: 25 }}\n />\n </Animated.View>\n </GestureDetector>\n\n {showRangeLabels &&\n rangeLabelSteps.map((rangeStep) => (\n <Pressable\n key={`label-${rangeStep}`}\n style={[\n tw.style('absolute items-center'),\n {\n top: RANGE_LABEL_TOP,\n left: getDotLeftPercent(rangeStep) as ViewStyle['left'],\n transform: [{ translateX: '-50%' }],\n },\n ]}\n onPress={() => handlePressStep(rangeStep)}\n disabled={isDisabled}\n accessibilityRole=\"button\"\n >\n <Text\n variant={TextVariant.BodyMd}\n fontWeight={FontWeight.Medium}\n color={TextColor.TextAlternative}\n >\n {formatLabel(rangeStep)}\n </Text>\n </Pressable>\n ))}\n </Box>\n );\n};\n\nSlider.displayName = 'Slider';\n"]}
@@ -0,0 +1,3 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ //# sourceMappingURL=Slider.types.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Slider.types.cjs","sourceRoot":"","sources":["../../../src/components/Slider/Slider.types.ts"],"names":[],"mappings":"","sourcesContent":["import type { SliderPropsShared } from '@metamask/design-system-shared';\nimport type { ViewProps } from 'react-native';\nimport type { Gesture } from 'react-native-gesture-handler';\nimport type { useAnimatedStyle } from 'react-native-reanimated';\n\n/**\n * React Native Slider props.\n *\n * Extends {@link SliderPropsShared} for cross-platform API (value, range, labels,\n * custom scale hooks) and `ViewProps` for root container passthrough (e.g.\n * `testID`, `accessibilityLabel`). See README for consumer-facing prop docs.\n */\nexport type SliderProps = SliderPropsShared &\n ViewProps & {\n /**\n * Horizontal inset on the root container so the thumb can overhang the track\n * at min/max without clipping. Defaults to {@link SLIDER_TRACK_INSET} (16);\n * override when the parent already provides edge padding.\n *\n * @default 16\n */\n trackInset?: number;\n\n /**\n * Optional twrnc classes merged into the root container after component defaults.\n * Use for layout spacing the Box API does not cover (e.g. `mt-4`).\n */\n twClassName?: string;\n };\n\n/**\n * Inputs for `useSliderGesture` — gesture handling and animated thumb/fill sync.\n *\n * Only `value` and `onValueChange` are required. Remaining fields default to the\n * same values as {@link SliderPropsShared} when omitted.\n */\nexport type UseSliderGestureParams = {\n /** Controlled domain value (`minimumValue`…`maximumValue`). */\n value: number;\n\n /**\n * Lower bound of the domain range.\n *\n * @default 0\n */\n minimumValue?: number;\n\n /**\n * Upper bound of the domain range.\n *\n * @default 100\n */\n maximumValue?: number;\n\n /**\n * Step increment applied by the default `mapTrackPercentToValue` mapper.\n * Custom mappers handle stepping inside `mapTrackPercentToValue`.\n *\n * @default 1\n */\n step?: number;\n\n /**\n * When true, pan/tap gestures and range-label presses are disabled.\n *\n * @default false\n */\n isDisabled?: boolean;\n\n /**\n * Called on every value change during pan drag, track tap, or range-label press.\n * Bridged from UI-thread worklets via `runOnJS`.\n */\n onValueChange: (value: number) => void;\n\n /**\n * Called when a gesture completes (finger lift, tap, or label press).\n * Omitted when the parent does not pass `onDragEnd`.\n */\n onDragEnd?: (value: number) => void;\n\n /**\n * Fires once when pan begins and once when pan ends; not fired on tap or\n * range-label press. Use for haptic feedback (e.g. ImpactMoment.SliderGrip).\n */\n onGrip?: () => void;\n\n /**\n * Called when track percent crosses a `tickThresholds` entry while dragging.\n * Evaluated on each pan `onUpdate` and on range-label press.\n */\n onTick?: () => void;\n\n /**\n * Track-percent positions (0–100) that trigger `onTick` when crossed.\n * Not domain values — use the same coordinate system as `rangeLabelSteps`.\n *\n * @default [25, 50, 75]\n */\n tickThresholds?: readonly number[];\n\n /**\n * Maps domain value → 0–100 track position for thumb/fill sync.\n * Must be a Reanimated worklet when provided (`'worklet';` in the function body).\n */\n mapValueToTrackPercent?: (value: number) => number;\n\n /**\n * Maps 0–100 track position → domain value during gestures.\n * Apply step rounding and snapping here for non-linear scales.\n * Must be a Reanimated worklet when provided (`'worklet';` in the function body).\n */\n mapTrackPercentToValue?: (trackPercent: number) => number;\n\n /**\n * Converts a tapped `rangeLabelSteps` entry to a domain value.\n * Default: `(step / 100) * (max - min) + min`.\n */\n stepToValue?: (step: number) => number;\n};\n\n/**\n * Return value of `useSliderGesture`.\n *\n * Wire `handleLayout`, animated styles, and `gesture` into `Slider.tsx`;\n * `handlePressStep` is bound to range-label `Pressable` targets.\n */\nexport type UseSliderGestureResult = {\n /**\n * Root `onLayout` handler. Stores track width and re-syncs thumb position\n * from the current `value` prop.\n */\n handleLayout: (event: { nativeEvent: { layout: { width: number } } }) => void;\n\n /** Animated width for the filled portion of the track (follows thumb). */\n progressStyle: ReturnType<typeof useAnimatedStyle>;\n\n /** Animated `translateX` for the thumb relative to the track start. */\n thumbStyle: ReturnType<typeof useAnimatedStyle>;\n\n /** Combined pan + tap gesture for the track/thumb hit area. */\n gesture: ReturnType<typeof Gesture.Simultaneous>;\n\n /**\n * Sets value from a tapped range label: `stepToValue` → callbacks → thumb sync.\n * No-op when `isDisabled` is true.\n */\n handlePressStep: (rangeStep: number) => void;\n};\n"]}