@metamask/design-system-react-native 0.33.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 (99) hide show
  1. package/CHANGELOG.md +30 -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/BottomSheetDialog/BottomSheetDialog.cjs +6 -5
  7. package/dist/components/BottomSheetDialog/BottomSheetDialog.cjs.map +1 -1
  8. package/dist/components/BottomSheetDialog/BottomSheetDialog.mjs +7 -6
  9. package/dist/components/BottomSheetDialog/BottomSheetDialog.mjs.map +1 -1
  10. package/dist/components/ButtonBase/ButtonBase.cjs +1 -1
  11. package/dist/components/ButtonBase/ButtonBase.cjs.map +1 -1
  12. package/dist/components/ButtonBase/ButtonBase.d.cts.map +1 -1
  13. package/dist/components/ButtonBase/ButtonBase.d.mts.map +1 -1
  14. package/dist/components/ButtonBase/ButtonBase.mjs +1 -1
  15. package/dist/components/ButtonBase/ButtonBase.mjs.map +1 -1
  16. package/dist/components/FilterButton/FilterButton.cjs +24 -36
  17. package/dist/components/FilterButton/FilterButton.cjs.map +1 -1
  18. package/dist/components/FilterButton/FilterButton.d.cts.map +1 -1
  19. package/dist/components/FilterButton/FilterButton.d.mts.map +1 -1
  20. package/dist/components/FilterButton/FilterButton.mjs +25 -37
  21. package/dist/components/FilterButton/FilterButton.mjs.map +1 -1
  22. package/dist/components/Icon/Icon.assets.cjs +2 -0
  23. package/dist/components/Icon/Icon.assets.cjs.map +1 -1
  24. package/dist/components/Icon/Icon.assets.d.cts.map +1 -1
  25. package/dist/components/Icon/Icon.assets.d.mts.map +1 -1
  26. package/dist/components/Icon/Icon.assets.mjs +2 -0
  27. package/dist/components/Icon/Icon.assets.mjs.map +1 -1
  28. package/dist/components/Icon/assets/candlestick-filled.svg +1 -0
  29. package/dist/components/Slider/Slider.cjs +139 -0
  30. package/dist/components/Slider/Slider.cjs.map +1 -0
  31. package/dist/components/Slider/Slider.constants.cjs +36 -0
  32. package/dist/components/Slider/Slider.constants.cjs.map +1 -0
  33. package/dist/components/Slider/Slider.constants.d.cts +33 -0
  34. package/dist/components/Slider/Slider.constants.d.cts.map +1 -0
  35. package/dist/components/Slider/Slider.constants.d.mts +33 -0
  36. package/dist/components/Slider/Slider.constants.d.mts.map +1 -0
  37. package/dist/components/Slider/Slider.constants.mjs +33 -0
  38. package/dist/components/Slider/Slider.constants.mjs.map +1 -0
  39. package/dist/components/Slider/Slider.d.cts +7 -0
  40. package/dist/components/Slider/Slider.d.cts.map +1 -0
  41. package/dist/components/Slider/Slider.d.mts +7 -0
  42. package/dist/components/Slider/Slider.d.mts.map +1 -0
  43. package/dist/components/Slider/Slider.mjs +116 -0
  44. package/dist/components/Slider/Slider.mjs.map +1 -0
  45. package/dist/components/Slider/Slider.types.cjs +3 -0
  46. package/dist/components/Slider/Slider.types.cjs.map +1 -0
  47. package/dist/components/Slider/Slider.types.d.cts +135 -0
  48. package/dist/components/Slider/Slider.types.d.cts.map +1 -0
  49. package/dist/components/Slider/Slider.types.d.mts +135 -0
  50. package/dist/components/Slider/Slider.types.d.mts.map +1 -0
  51. package/dist/components/Slider/Slider.types.mjs +2 -0
  52. package/dist/components/Slider/Slider.types.mjs.map +1 -0
  53. package/dist/components/Slider/Slider.utilities.cjs +202 -0
  54. package/dist/components/Slider/Slider.utilities.cjs.map +1 -0
  55. package/dist/components/Slider/Slider.utilities.d.cts +108 -0
  56. package/dist/components/Slider/Slider.utilities.d.cts.map +1 -0
  57. package/dist/components/Slider/Slider.utilities.d.mts +108 -0
  58. package/dist/components/Slider/Slider.utilities.d.mts.map +1 -0
  59. package/dist/components/Slider/Slider.utilities.mjs +186 -0
  60. package/dist/components/Slider/Slider.utilities.mjs.map +1 -0
  61. package/dist/components/Slider/index.cjs +9 -0
  62. package/dist/components/Slider/index.cjs.map +1 -0
  63. package/dist/components/Slider/index.d.cts +4 -0
  64. package/dist/components/Slider/index.d.cts.map +1 -0
  65. package/dist/components/Slider/index.d.mts +4 -0
  66. package/dist/components/Slider/index.d.mts.map +1 -0
  67. package/dist/components/Slider/index.mjs +3 -0
  68. package/dist/components/Slider/index.mjs.map +1 -0
  69. package/dist/components/Slider/useSliderGesture.cjs +219 -0
  70. package/dist/components/Slider/useSliderGesture.cjs.map +1 -0
  71. package/dist/components/Slider/useSliderGesture.d.cts +17 -0
  72. package/dist/components/Slider/useSliderGesture.d.cts.map +1 -0
  73. package/dist/components/Slider/useSliderGesture.d.mts +17 -0
  74. package/dist/components/Slider/useSliderGesture.d.mts.map +1 -0
  75. package/dist/components/Slider/useSliderGesture.mjs +215 -0
  76. package/dist/components/Slider/useSliderGesture.mjs.map +1 -0
  77. package/dist/components/Toast/Toaster.cjs +7 -3
  78. package/dist/components/Toast/Toaster.cjs.map +1 -1
  79. package/dist/components/Toast/Toaster.d.cts.map +1 -1
  80. package/dist/components/Toast/Toaster.d.mts.map +1 -1
  81. package/dist/components/Toast/Toaster.mjs +8 -4
  82. package/dist/components/Toast/Toaster.mjs.map +1 -1
  83. package/dist/components/index.cjs +5 -1
  84. package/dist/components/index.cjs.map +1 -1
  85. package/dist/components/index.d.cts +2 -0
  86. package/dist/components/index.d.cts.map +1 -1
  87. package/dist/components/index.d.mts +2 -0
  88. package/dist/components/index.d.mts.map +1 -1
  89. package/dist/components/index.mjs +1 -0
  90. package/dist/components/index.mjs.map +1 -1
  91. package/dist/index.cjs +0 -4
  92. package/dist/index.cjs.map +1 -1
  93. package/dist/index.d.cts +0 -1
  94. package/dist/index.d.cts.map +1 -1
  95. package/dist/index.d.mts +0 -1
  96. package/dist/index.d.mts.map +1 -1
  97. package/dist/index.mjs +0 -4
  98. package/dist/index.mjs.map +1 -1
  99. package/package.json +7 -8
@@ -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"]}
@@ -0,0 +1,135 @@
1
+ import type { SliderPropsShared } from "@metamask/design-system-shared";
2
+ import type { ViewProps } from "react-native";
3
+ import type { Gesture } from "react-native-gesture-handler";
4
+ import type { useAnimatedStyle } from "react-native-reanimated";
5
+ /**
6
+ * React Native Slider props.
7
+ *
8
+ * Extends {@link SliderPropsShared} for cross-platform API (value, range, labels,
9
+ * custom scale hooks) and `ViewProps` for root container passthrough (e.g.
10
+ * `testID`, `accessibilityLabel`). See README for consumer-facing prop docs.
11
+ */
12
+ export type SliderProps = SliderPropsShared & ViewProps & {
13
+ /**
14
+ * Horizontal inset on the root container so the thumb can overhang the track
15
+ * at min/max without clipping. Defaults to {@link SLIDER_TRACK_INSET} (16);
16
+ * override when the parent already provides edge padding.
17
+ *
18
+ * @default 16
19
+ */
20
+ trackInset?: number;
21
+ /**
22
+ * Optional twrnc classes merged into the root container after component defaults.
23
+ * Use for layout spacing the Box API does not cover (e.g. `mt-4`).
24
+ */
25
+ twClassName?: string;
26
+ };
27
+ /**
28
+ * Inputs for `useSliderGesture` — gesture handling and animated thumb/fill sync.
29
+ *
30
+ * Only `value` and `onValueChange` are required. Remaining fields default to the
31
+ * same values as {@link SliderPropsShared} when omitted.
32
+ */
33
+ export type UseSliderGestureParams = {
34
+ /** Controlled domain value (`minimumValue`…`maximumValue`). */
35
+ value: number;
36
+ /**
37
+ * Lower bound of the domain range.
38
+ *
39
+ * @default 0
40
+ */
41
+ minimumValue?: number;
42
+ /**
43
+ * Upper bound of the domain range.
44
+ *
45
+ * @default 100
46
+ */
47
+ maximumValue?: number;
48
+ /**
49
+ * Step increment applied by the default `mapTrackPercentToValue` mapper.
50
+ * Custom mappers handle stepping inside `mapTrackPercentToValue`.
51
+ *
52
+ * @default 1
53
+ */
54
+ step?: number;
55
+ /**
56
+ * When true, pan/tap gestures and range-label presses are disabled.
57
+ *
58
+ * @default false
59
+ */
60
+ isDisabled?: boolean;
61
+ /**
62
+ * Called on every value change during pan drag, track tap, or range-label press.
63
+ * Bridged from UI-thread worklets via `runOnJS`.
64
+ */
65
+ onValueChange: (value: number) => void;
66
+ /**
67
+ * Called when a gesture completes (finger lift, tap, or label press).
68
+ * Omitted when the parent does not pass `onDragEnd`.
69
+ */
70
+ onDragEnd?: (value: number) => void;
71
+ /**
72
+ * Fires once when pan begins and once when pan ends; not fired on tap or
73
+ * range-label press. Use for haptic feedback (e.g. ImpactMoment.SliderGrip).
74
+ */
75
+ onGrip?: () => void;
76
+ /**
77
+ * Called when track percent crosses a `tickThresholds` entry while dragging.
78
+ * Evaluated on each pan `onUpdate` and on range-label press.
79
+ */
80
+ onTick?: () => void;
81
+ /**
82
+ * Track-percent positions (0–100) that trigger `onTick` when crossed.
83
+ * Not domain values — use the same coordinate system as `rangeLabelSteps`.
84
+ *
85
+ * @default [25, 50, 75]
86
+ */
87
+ tickThresholds?: readonly number[];
88
+ /**
89
+ * Maps domain value → 0–100 track position for thumb/fill sync.
90
+ * Must be a Reanimated worklet when provided (`'worklet';` in the function body).
91
+ */
92
+ mapValueToTrackPercent?: (value: number) => number;
93
+ /**
94
+ * Maps 0–100 track position → domain value during gestures.
95
+ * Apply step rounding and snapping here for non-linear scales.
96
+ * Must be a Reanimated worklet when provided (`'worklet';` in the function body).
97
+ */
98
+ mapTrackPercentToValue?: (trackPercent: number) => number;
99
+ /**
100
+ * Converts a tapped `rangeLabelSteps` entry to a domain value.
101
+ * Default: `(step / 100) * (max - min) + min`.
102
+ */
103
+ stepToValue?: (step: number) => number;
104
+ };
105
+ /**
106
+ * Return value of `useSliderGesture`.
107
+ *
108
+ * Wire `handleLayout`, animated styles, and `gesture` into `Slider.tsx`;
109
+ * `handlePressStep` is bound to range-label `Pressable` targets.
110
+ */
111
+ export type UseSliderGestureResult = {
112
+ /**
113
+ * Root `onLayout` handler. Stores track width and re-syncs thumb position
114
+ * from the current `value` prop.
115
+ */
116
+ handleLayout: (event: {
117
+ nativeEvent: {
118
+ layout: {
119
+ width: number;
120
+ };
121
+ };
122
+ }) => void;
123
+ /** Animated width for the filled portion of the track (follows thumb). */
124
+ progressStyle: ReturnType<typeof useAnimatedStyle>;
125
+ /** Animated `translateX` for the thumb relative to the track start. */
126
+ thumbStyle: ReturnType<typeof useAnimatedStyle>;
127
+ /** Combined pan + tap gesture for the track/thumb hit area. */
128
+ gesture: ReturnType<typeof Gesture.Simultaneous>;
129
+ /**
130
+ * Sets value from a tapped range label: `stepToValue` → callbacks → thumb sync.
131
+ * No-op when `isDisabled` is true.
132
+ */
133
+ handlePressStep: (rangeStep: number) => void;
134
+ };
135
+ //# sourceMappingURL=Slider.types.d.cts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Slider.types.d.cts","sourceRoot":"","sources":["../../../src/components/Slider/Slider.types.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,iBAAiB,EAAE,uCAAuC;AACxE,OAAO,KAAK,EAAE,SAAS,EAAE,qBAAqB;AAC9C,OAAO,KAAK,EAAE,OAAO,EAAE,qCAAqC;AAC5D,OAAO,KAAK,EAAE,gBAAgB,EAAE,gCAAgC;AAEhE;;;;;;GAMG;AACH,MAAM,MAAM,WAAW,GAAG,iBAAiB,GACzC,SAAS,GAAG;IACV;;;;;;OAMG;IACH,UAAU,CAAC,EAAE,MAAM,CAAC;IAEpB;;;OAGG;IACH,WAAW,CAAC,EAAE,MAAM,CAAC;CACtB,CAAC;AAEJ;;;;;GAKG;AACH,MAAM,MAAM,sBAAsB,GAAG;IACnC,+DAA+D;IAC/D,KAAK,EAAE,MAAM,CAAC;IAEd;;;;OAIG;IACH,YAAY,CAAC,EAAE,MAAM,CAAC;IAEtB;;;;OAIG;IACH,YAAY,CAAC,EAAE,MAAM,CAAC;IAEtB;;;;;OAKG;IACH,IAAI,CAAC,EAAE,MAAM,CAAC;IAEd;;;;OAIG;IACH,UAAU,CAAC,EAAE,OAAO,CAAC;IAErB;;;OAGG;IACH,aAAa,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,IAAI,CAAC;IAEvC;;;OAGG;IACH,SAAS,CAAC,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,IAAI,CAAC;IAEpC;;;OAGG;IACH,MAAM,CAAC,EAAE,MAAM,IAAI,CAAC;IAEpB;;;OAGG;IACH,MAAM,CAAC,EAAE,MAAM,IAAI,CAAC;IAEpB;;;;;OAKG;IACH,cAAc,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;IAEnC;;;OAGG;IACH,sBAAsB,CAAC,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,MAAM,CAAC;IAEnD;;;;OAIG;IACH,sBAAsB,CAAC,EAAE,CAAC,YAAY,EAAE,MAAM,KAAK,MAAM,CAAC;IAE1D;;;OAGG;IACH,WAAW,CAAC,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,MAAM,CAAC;CACxC,CAAC;AAEF;;;;;GAKG;AACH,MAAM,MAAM,sBAAsB,GAAG;IACnC;;;OAGG;IACH,YAAY,EAAE,CAAC,KAAK,EAAE;QAAE,WAAW,EAAE;YAAE,MAAM,EAAE;gBAAE,KAAK,EAAE,MAAM,CAAA;aAAE,CAAA;SAAE,CAAA;KAAE,KAAK,IAAI,CAAC;IAE9E,0EAA0E;IAC1E,aAAa,EAAE,UAAU,CAAC,OAAO,gBAAgB,CAAC,CAAC;IAEnD,uEAAuE;IACvE,UAAU,EAAE,UAAU,CAAC,OAAO,gBAAgB,CAAC,CAAC;IAEhD,+DAA+D;IAC/D,OAAO,EAAE,UAAU,CAAC,OAAO,OAAO,CAAC,YAAY,CAAC,CAAC;IAEjD;;;OAGG;IACH,eAAe,EAAE,CAAC,SAAS,EAAE,MAAM,KAAK,IAAI,CAAC;CAC9C,CAAC"}
@@ -0,0 +1,135 @@
1
+ import type { SliderPropsShared } from "@metamask/design-system-shared";
2
+ import type { ViewProps } from "react-native";
3
+ import type { Gesture } from "react-native-gesture-handler";
4
+ import type { useAnimatedStyle } from "react-native-reanimated";
5
+ /**
6
+ * React Native Slider props.
7
+ *
8
+ * Extends {@link SliderPropsShared} for cross-platform API (value, range, labels,
9
+ * custom scale hooks) and `ViewProps` for root container passthrough (e.g.
10
+ * `testID`, `accessibilityLabel`). See README for consumer-facing prop docs.
11
+ */
12
+ export type SliderProps = SliderPropsShared & ViewProps & {
13
+ /**
14
+ * Horizontal inset on the root container so the thumb can overhang the track
15
+ * at min/max without clipping. Defaults to {@link SLIDER_TRACK_INSET} (16);
16
+ * override when the parent already provides edge padding.
17
+ *
18
+ * @default 16
19
+ */
20
+ trackInset?: number;
21
+ /**
22
+ * Optional twrnc classes merged into the root container after component defaults.
23
+ * Use for layout spacing the Box API does not cover (e.g. `mt-4`).
24
+ */
25
+ twClassName?: string;
26
+ };
27
+ /**
28
+ * Inputs for `useSliderGesture` — gesture handling and animated thumb/fill sync.
29
+ *
30
+ * Only `value` and `onValueChange` are required. Remaining fields default to the
31
+ * same values as {@link SliderPropsShared} when omitted.
32
+ */
33
+ export type UseSliderGestureParams = {
34
+ /** Controlled domain value (`minimumValue`…`maximumValue`). */
35
+ value: number;
36
+ /**
37
+ * Lower bound of the domain range.
38
+ *
39
+ * @default 0
40
+ */
41
+ minimumValue?: number;
42
+ /**
43
+ * Upper bound of the domain range.
44
+ *
45
+ * @default 100
46
+ */
47
+ maximumValue?: number;
48
+ /**
49
+ * Step increment applied by the default `mapTrackPercentToValue` mapper.
50
+ * Custom mappers handle stepping inside `mapTrackPercentToValue`.
51
+ *
52
+ * @default 1
53
+ */
54
+ step?: number;
55
+ /**
56
+ * When true, pan/tap gestures and range-label presses are disabled.
57
+ *
58
+ * @default false
59
+ */
60
+ isDisabled?: boolean;
61
+ /**
62
+ * Called on every value change during pan drag, track tap, or range-label press.
63
+ * Bridged from UI-thread worklets via `runOnJS`.
64
+ */
65
+ onValueChange: (value: number) => void;
66
+ /**
67
+ * Called when a gesture completes (finger lift, tap, or label press).
68
+ * Omitted when the parent does not pass `onDragEnd`.
69
+ */
70
+ onDragEnd?: (value: number) => void;
71
+ /**
72
+ * Fires once when pan begins and once when pan ends; not fired on tap or
73
+ * range-label press. Use for haptic feedback (e.g. ImpactMoment.SliderGrip).
74
+ */
75
+ onGrip?: () => void;
76
+ /**
77
+ * Called when track percent crosses a `tickThresholds` entry while dragging.
78
+ * Evaluated on each pan `onUpdate` and on range-label press.
79
+ */
80
+ onTick?: () => void;
81
+ /**
82
+ * Track-percent positions (0–100) that trigger `onTick` when crossed.
83
+ * Not domain values — use the same coordinate system as `rangeLabelSteps`.
84
+ *
85
+ * @default [25, 50, 75]
86
+ */
87
+ tickThresholds?: readonly number[];
88
+ /**
89
+ * Maps domain value → 0–100 track position for thumb/fill sync.
90
+ * Must be a Reanimated worklet when provided (`'worklet';` in the function body).
91
+ */
92
+ mapValueToTrackPercent?: (value: number) => number;
93
+ /**
94
+ * Maps 0–100 track position → domain value during gestures.
95
+ * Apply step rounding and snapping here for non-linear scales.
96
+ * Must be a Reanimated worklet when provided (`'worklet';` in the function body).
97
+ */
98
+ mapTrackPercentToValue?: (trackPercent: number) => number;
99
+ /**
100
+ * Converts a tapped `rangeLabelSteps` entry to a domain value.
101
+ * Default: `(step / 100) * (max - min) + min`.
102
+ */
103
+ stepToValue?: (step: number) => number;
104
+ };
105
+ /**
106
+ * Return value of `useSliderGesture`.
107
+ *
108
+ * Wire `handleLayout`, animated styles, and `gesture` into `Slider.tsx`;
109
+ * `handlePressStep` is bound to range-label `Pressable` targets.
110
+ */
111
+ export type UseSliderGestureResult = {
112
+ /**
113
+ * Root `onLayout` handler. Stores track width and re-syncs thumb position
114
+ * from the current `value` prop.
115
+ */
116
+ handleLayout: (event: {
117
+ nativeEvent: {
118
+ layout: {
119
+ width: number;
120
+ };
121
+ };
122
+ }) => void;
123
+ /** Animated width for the filled portion of the track (follows thumb). */
124
+ progressStyle: ReturnType<typeof useAnimatedStyle>;
125
+ /** Animated `translateX` for the thumb relative to the track start. */
126
+ thumbStyle: ReturnType<typeof useAnimatedStyle>;
127
+ /** Combined pan + tap gesture for the track/thumb hit area. */
128
+ gesture: ReturnType<typeof Gesture.Simultaneous>;
129
+ /**
130
+ * Sets value from a tapped range label: `stepToValue` → callbacks → thumb sync.
131
+ * No-op when `isDisabled` is true.
132
+ */
133
+ handlePressStep: (rangeStep: number) => void;
134
+ };
135
+ //# sourceMappingURL=Slider.types.d.mts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Slider.types.d.mts","sourceRoot":"","sources":["../../../src/components/Slider/Slider.types.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,iBAAiB,EAAE,uCAAuC;AACxE,OAAO,KAAK,EAAE,SAAS,EAAE,qBAAqB;AAC9C,OAAO,KAAK,EAAE,OAAO,EAAE,qCAAqC;AAC5D,OAAO,KAAK,EAAE,gBAAgB,EAAE,gCAAgC;AAEhE;;;;;;GAMG;AACH,MAAM,MAAM,WAAW,GAAG,iBAAiB,GACzC,SAAS,GAAG;IACV;;;;;;OAMG;IACH,UAAU,CAAC,EAAE,MAAM,CAAC;IAEpB;;;OAGG;IACH,WAAW,CAAC,EAAE,MAAM,CAAC;CACtB,CAAC;AAEJ;;;;;GAKG;AACH,MAAM,MAAM,sBAAsB,GAAG;IACnC,+DAA+D;IAC/D,KAAK,EAAE,MAAM,CAAC;IAEd;;;;OAIG;IACH,YAAY,CAAC,EAAE,MAAM,CAAC;IAEtB;;;;OAIG;IACH,YAAY,CAAC,EAAE,MAAM,CAAC;IAEtB;;;;;OAKG;IACH,IAAI,CAAC,EAAE,MAAM,CAAC;IAEd;;;;OAIG;IACH,UAAU,CAAC,EAAE,OAAO,CAAC;IAErB;;;OAGG;IACH,aAAa,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,IAAI,CAAC;IAEvC;;;OAGG;IACH,SAAS,CAAC,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,IAAI,CAAC;IAEpC;;;OAGG;IACH,MAAM,CAAC,EAAE,MAAM,IAAI,CAAC;IAEpB;;;OAGG;IACH,MAAM,CAAC,EAAE,MAAM,IAAI,CAAC;IAEpB;;;;;OAKG;IACH,cAAc,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;IAEnC;;;OAGG;IACH,sBAAsB,CAAC,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,MAAM,CAAC;IAEnD;;;;OAIG;IACH,sBAAsB,CAAC,EAAE,CAAC,YAAY,EAAE,MAAM,KAAK,MAAM,CAAC;IAE1D;;;OAGG;IACH,WAAW,CAAC,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,MAAM,CAAC;CACxC,CAAC;AAEF;;;;;GAKG;AACH,MAAM,MAAM,sBAAsB,GAAG;IACnC;;;OAGG;IACH,YAAY,EAAE,CAAC,KAAK,EAAE;QAAE,WAAW,EAAE;YAAE,MAAM,EAAE;gBAAE,KAAK,EAAE,MAAM,CAAA;aAAE,CAAA;SAAE,CAAA;KAAE,KAAK,IAAI,CAAC;IAE9E,0EAA0E;IAC1E,aAAa,EAAE,UAAU,CAAC,OAAO,gBAAgB,CAAC,CAAC;IAEnD,uEAAuE;IACvE,UAAU,EAAE,UAAU,CAAC,OAAO,gBAAgB,CAAC,CAAC;IAEhD,+DAA+D;IAC/D,OAAO,EAAE,UAAU,CAAC,OAAO,OAAO,CAAC,YAAY,CAAC,CAAC;IAEjD;;;OAGG;IACH,eAAe,EAAE,CAAC,SAAS,EAAE,MAAM,KAAK,IAAI,CAAC;CAC9C,CAAC"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=Slider.types.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Slider.types.mjs","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"]}
@@ -0,0 +1,202 @@
1
+ "use strict";
2
+ /**
3
+ * Pure helpers for Slider coordinate conversion and UI defaults.
4
+ *
5
+ * Three coordinate systems:
6
+ * - **Domain value** — the controlled `value` prop (`minimumValue`…`maximumValue`).
7
+ * - **Track percent** — normalized 0–100 position along the track (used for dots,
8
+ * labels, and `tickThresholds`; may be non-linear via `map*` hooks).
9
+ * - **Pixel position** — thumb/fill offset in layout pixels (`translateX`).
10
+ *
11
+ * Functions marked with `'worklet'` run on the UI thread inside gesture handlers.
12
+ * JS-thread callers use the non-worklet wrappers (`getTrackPercentFromValue`, etc.).
13
+ */
14
+ Object.defineProperty(exports, "__esModule", { value: true });
15
+ exports.clampValueToRange = exports.getDotLeftPercent = exports.defaultFormatStepLabel = exports.defaultStepToValue = exports.getTrackPercentFromValue = exports.clampGesturePosition = exports.positionToTrackPercent = exports.trackPercentToPosition = exports.resolveValueToTrackPercent = exports.resolveTrackPercentToValue = exports.defaultMapTrackPercentToValue = exports.defaultMapValueToTrackPercent = exports.clampTrackPercent = void 0;
16
+ const Slider_constants_1 = require("./Slider.constants.cjs");
17
+ // --- Track-percent primitives (worklet) ---
18
+ function clampTrackPercent(trackPercent) {
19
+ 'worklet';
20
+ return Math.max(0, Math.min(100, trackPercent));
21
+ }
22
+ exports.clampTrackPercent = clampTrackPercent;
23
+ // --- Domain ↔ track-percent mappers (worklet) ---
24
+ /**
25
+ * Linear default: domain value → 0–100 track position.
26
+ *
27
+ * @param value - Domain value to map.
28
+ * @param minimumValue - Lower bound of the domain range.
29
+ * @param maximumValue - Upper bound of the domain range.
30
+ * @returns Track percent clamped to 0–100.
31
+ */
32
+ function defaultMapValueToTrackPercent(value, minimumValue, maximumValue) {
33
+ 'worklet';
34
+ const range = maximumValue - minimumValue;
35
+ if (range === 0) {
36
+ return 0;
37
+ }
38
+ const percent = ((value - minimumValue) / range) * 100;
39
+ return clampTrackPercent(percent);
40
+ }
41
+ exports.defaultMapValueToTrackPercent = defaultMapValueToTrackPercent;
42
+ /**
43
+ * Linear default: track position → stepped domain value.
44
+ *
45
+ * @param trackPercent - Track position from 0–100.
46
+ * @param minimumValue - Lower bound of the domain range.
47
+ * @param maximumValue - Upper bound of the domain range.
48
+ * @param step - Step increment for rounding.
49
+ * @returns Stepped domain value clamped to the range.
50
+ */
51
+ function defaultMapTrackPercentToValue(trackPercent, minimumValue, maximumValue, step) {
52
+ 'worklet';
53
+ const range = maximumValue - minimumValue;
54
+ if (range === 0) {
55
+ return minimumValue;
56
+ }
57
+ const rawValue = (clampTrackPercent(trackPercent) / 100) * range + minimumValue;
58
+ const stepped = Math.round(rawValue / step) * step;
59
+ return Math.max(minimumValue, Math.min(maximumValue, stepped));
60
+ }
61
+ exports.defaultMapTrackPercentToValue = defaultMapTrackPercentToValue;
62
+ /**
63
+ * UI-thread entry: custom `mapTrackPercentToValue` or linear default.
64
+ *
65
+ * @param trackPercent - Track position from 0–100.
66
+ * @param minimumValue - Lower bound of the domain range.
67
+ * @param maximumValue - Upper bound of the domain range.
68
+ * @param step - Step increment for the default mapper.
69
+ * @param mapTrackPercentToValue - Optional custom mapper.
70
+ * @returns Domain value for the track position.
71
+ */
72
+ function resolveTrackPercentToValue(trackPercent, minimumValue, maximumValue, step, mapTrackPercentToValue) {
73
+ 'worklet';
74
+ if (mapTrackPercentToValue) {
75
+ return mapTrackPercentToValue(trackPercent);
76
+ }
77
+ return defaultMapTrackPercentToValue(trackPercent, minimumValue, maximumValue, step);
78
+ }
79
+ exports.resolveTrackPercentToValue = resolveTrackPercentToValue;
80
+ /**
81
+ * UI-thread entry: custom `mapValueToTrackPercent` or linear default.
82
+ *
83
+ * @param value - Domain value to map.
84
+ * @param minimumValue - Lower bound of the domain range.
85
+ * @param maximumValue - Upper bound of the domain range.
86
+ * @param mapValueToTrackPercent - Optional custom mapper.
87
+ * @returns Track percent for the domain value.
88
+ */
89
+ function resolveValueToTrackPercent(value, minimumValue, maximumValue, mapValueToTrackPercent) {
90
+ 'worklet';
91
+ if (mapValueToTrackPercent) {
92
+ return mapValueToTrackPercent(value);
93
+ }
94
+ return defaultMapValueToTrackPercent(value, minimumValue, maximumValue);
95
+ }
96
+ exports.resolveValueToTrackPercent = resolveValueToTrackPercent;
97
+ // --- Track-percent ↔ pixel position (worklet) ---
98
+ function trackPercentToPosition(trackPercent, width) {
99
+ 'worklet';
100
+ if (width === 0) {
101
+ return 0;
102
+ }
103
+ return (clampTrackPercent(trackPercent) / 100) * width;
104
+ }
105
+ exports.trackPercentToPosition = trackPercentToPosition;
106
+ function positionToTrackPercent(position, width) {
107
+ 'worklet';
108
+ if (width === 0) {
109
+ return 0;
110
+ }
111
+ return clampTrackPercent((position / width) * 100);
112
+ }
113
+ exports.positionToTrackPercent = positionToTrackPercent;
114
+ /**
115
+ * Clamps a touch X coordinate to the track bounds.
116
+ *
117
+ * @param position - Touch X in track coordinates.
118
+ * @param width - Track width in pixels.
119
+ * @returns Clamped pixel position.
120
+ */
121
+ function clampGesturePosition(position, width) {
122
+ 'worklet';
123
+ return Math.max(0, Math.min(position, width));
124
+ }
125
+ exports.clampGesturePosition = clampGesturePosition;
126
+ // --- JS-thread domain ↔ track-percent ---
127
+ /**
128
+ * JS-thread entry for mapping domain value → track percent.
129
+ * Used by Slider (labels, a11y) and useSliderGesture (prop/layout sync).
130
+ *
131
+ * @param value - Domain value to map.
132
+ * @param minimumValue - Lower bound of the domain range.
133
+ * @param maximumValue - Upper bound of the domain range.
134
+ * @param mapValueToTrackPercent - Optional custom mapper.
135
+ * @returns Track percent for the domain value.
136
+ */
137
+ function getTrackPercentFromValue(value, minimumValue, maximumValue, mapValueToTrackPercent) {
138
+ if (mapValueToTrackPercent) {
139
+ return mapValueToTrackPercent(value);
140
+ }
141
+ return defaultMapValueToTrackPercent(value, minimumValue, maximumValue);
142
+ }
143
+ exports.getTrackPercentFromValue = getTrackPercentFromValue;
144
+ // --- Range label / dot defaults (Slider.tsx) ---
145
+ /**
146
+ * Default `stepToValue`: linear track-percent → domain value.
147
+ *
148
+ * @param step - Track-percent step from `rangeLabelSteps`.
149
+ * @param minimumValue - Lower bound of the domain range.
150
+ * @param maximumValue - Upper bound of the domain range.
151
+ * @returns Domain value for the step.
152
+ */
153
+ function defaultStepToValue(step, minimumValue, maximumValue) {
154
+ return (step / 100) * (maximumValue - minimumValue) + minimumValue;
155
+ }
156
+ exports.defaultStepToValue = defaultStepToValue;
157
+ /**
158
+ * Default `formatStepLabel`: display track percent as a percent string.
159
+ *
160
+ * @param step - Track-percent step from `rangeLabelSteps`.
161
+ * @returns Formatted label string.
162
+ */
163
+ function defaultFormatStepLabel(step) {
164
+ return `${step}%`;
165
+ }
166
+ exports.defaultFormatStepLabel = defaultFormatStepLabel;
167
+ /**
168
+ * Marker `left` percent for range dots and labels; edge steps inset to stay on track.
169
+ *
170
+ * @param step - Track-percent step from `rangeLabelSteps`.
171
+ * @returns CSS `left` percentage string.
172
+ */
173
+ function getDotLeftPercent(step) {
174
+ if (step === 0) {
175
+ return Slider_constants_1.DOT_EDGE_INSET_PERCENT;
176
+ }
177
+ if (step === 100) {
178
+ return Slider_constants_1.DOT_EDGE_MAX_PERCENT;
179
+ }
180
+ return `${step}%`;
181
+ }
182
+ exports.getDotLeftPercent = getDotLeftPercent;
183
+ // --- Accessibility (Slider.tsx) ---
184
+ /**
185
+ * Clamps and steps a domain value for increment/decrement actions.
186
+ *
187
+ * @param value - Domain value to clamp.
188
+ * @param minimumValue - Lower bound of the domain range.
189
+ * @param maximumValue - Upper bound of the domain range.
190
+ * @param step - Step increment for rounding.
191
+ * @returns Clamped and stepped domain value.
192
+ */
193
+ function clampValueToRange(value, minimumValue, maximumValue, step) {
194
+ const range = maximumValue - minimumValue;
195
+ if (range === 0) {
196
+ return minimumValue;
197
+ }
198
+ const clamped = Math.max(minimumValue, Math.min(maximumValue, value));
199
+ return Math.round(clamped / step) * step;
200
+ }
201
+ exports.clampValueToRange = clampValueToRange;
202
+ //# sourceMappingURL=Slider.utilities.cjs.map