panelui-native 0.21.0 → 0.22.5

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.
package/README.md CHANGED
@@ -1,7 +1,7 @@
1
1
  # PanelUI — React Native UI components for Expo, styled with Tailwind CSS
2
2
 
3
3
  **PanelUI** (`panelui-native`) is an accessible, high-performance React Native component
4
- library for Expo apps. 29 typed components — buttons, bottom sheets, dialogs, selects,
4
+ library for Expo apps. 53 typed components — buttons, bottom sheets, dialogs, selects,
5
5
  toasts, forms — styled with Tailwind CSS v4 and animated on the UI thread with Reanimated.
6
6
  Zero native code, so it runs in Expo Go.
7
7
 
@@ -24,15 +24,35 @@ Zero native code, so it runs in Expo Go.
24
24
  state and labels.
25
25
  - 📦 **TypeScript, tree-shakeable, zero native modules** — works in Expo Go, no prebuild needed.
26
26
 
27
- ## Install
27
+ ## Quick start
28
+
29
+ Needs an Expo SDK 57+ app and Node 20+. No Xcode, no Android Studio, no `prebuild` — PanelUI has
30
+ no native modules, so it runs in Expo Go. No app yet? `npx create-expo-app@latest my-app`.
31
+
32
+ Five steps. The full walkthrough, with a fix for every error people hit, is at
33
+ **[panelui.dev/docs/installation](https://panelui.dev/docs/installation)**.
34
+
35
+ ### 1. Install the packages
28
36
 
29
37
  ```sh
30
- npx expo install panelui-native uniwind tailwindcss react-native-reanimated react-native-gesture-handler react-native-safe-area-context react-native-svg react-native-worklets
38
+ npx expo install panelui-native uniwind tailwindcss @react-native-masked-view/masked-view expo-linear-gradient react-native-gesture-handler react-native-reanimated react-native-safe-area-context react-native-svg react-native-worklets
31
39
  ```
32
40
 
33
- ## Quick start
41
+ Install all of them, including the ones you think you don't need. Metro resolves every import in
42
+ the library when it builds your bundle, so leaving one out fails the **first** bundle with
43
+ `Unable to resolve module …` — for a component you may never use. `npx expo install` (rather than
44
+ `npm install`) picks the versions that match your SDK.
45
+
46
+ Optional, each behind a guarded import: `expo-haptics` (the `haptics` prop), `expo-blur` (blurred
47
+ overlay backdrops), `expo-clipboard` (`useCopyToClipboard`), `react-native-keyboard-controller`
48
+ (keyboard avoidance on Android), `expo-file-system` + `react-native-view-shot` (Signature export),
49
+ `@expo/ui` (native platform controls).
34
50
 
35
- **1. Configure Metro**
51
+ ### 2. Add `metro.config.js`
52
+
53
+ **In the root of your project, next to `package.json`** — not in `app/`, not in `src/`. A Metro
54
+ config anywhere else is silently ignored and none of your classes will do anything. A fresh Expo
55
+ app has no such file; `npx expo customize metro.config.js` writes one.
36
56
 
37
57
  ```js
38
58
  // metro.config.js
@@ -42,49 +62,100 @@ const { withUniwindConfig } = require('uniwind/metro');
42
62
  const config = getDefaultConfig(__dirname);
43
63
 
44
64
  module.exports = withUniwindConfig(config, {
65
+ // In an app made by create-expo-app this is './src/global.css' — see step 3.
45
66
  cssEntryFile: './global.css',
46
67
  dtsFile: './uniwind-types.d.ts',
47
- // Only needed if you use the Moon or Grass themes.
68
+ // Only needed to switch to the Moon or Grass themes at runtime.
48
69
  extraThemes: ['moon', 'moon-dark', 'grass', 'grass-dark'],
49
70
  });
50
71
  ```
51
72
 
52
- **2. Create `global.css`**
73
+ `cssEntryFile` and `dtsFile` are relative to this file.
74
+
75
+ ### 3. Add the imports to `global.css`
76
+
77
+ **Look for this file before you create one** — an app made by `create-expo-app` already has
78
+ `src/global.css`. Add these lines at the top of it and leave the rest below. A second CSS file at
79
+ the project root gives you two entries, only one of which is compiled, and nothing gets styled.
53
80
 
54
81
  ```css
82
+ /* src/global.css */
55
83
  @import 'tailwindcss';
56
84
  @import 'uniwind';
57
85
  @import 'panelui-native/theme.css';
58
86
 
59
- @source './node_modules/panelui-native/src';
87
+ @source '../node_modules/panelui-native/src';
60
88
  ```
61
89
 
62
- **3. Wrap your app**
90
+ `@source` is relative to **the CSS file**, and has to land on `node_modules/panelui-native/src` —
91
+ hence the `../` above, from `src/`. From the project root it is `'./node_modules/…'`, from
92
+ `src/styles/` it is `'../../node_modules/…'`. Get it wrong and your own classes work while
93
+ PanelUI's components come out unstyled. Whichever file you used is what `cssEntryFile` must name.
94
+
95
+ ### 4. Import the CSS and add the provider
96
+
97
+ At the top of your app's entry file. The default template uses Expo Router with routes under
98
+ `src/`, so there is usually no `App.tsx` — the entry is `src/app/_layout.tsx`, and it already
99
+ returns a navigation `ThemeProvider` to wrap rather than replace:
63
100
 
64
101
  ```tsx
65
- // App.tsx
66
- import './global.css';
67
- import { PanelUIProvider, Button, Card } from 'panelui-native';
102
+ // src/app/_layout.tsx
103
+ import '../global.css';
104
+
105
+ import { DarkTheme, DefaultTheme, ThemeProvider } from 'expo-router';
106
+ import { useColorScheme } from 'react-native';
107
+ import { PanelUIProvider } from 'panelui-native';
108
+
109
+ import AppTabs from '@/components/app-tabs';
110
+
111
+ export default function RootLayout() {
112
+ const colorScheme = useColorScheme();
68
113
 
69
- export default function App() {
70
114
  return (
71
115
  <PanelUIProvider>
72
- <Card>
73
- <Card.Header>
74
- <Card.Title>Create project</Card.Title>
75
- <Card.Description>Deploy your new project in one click.</Card.Description>
76
- </Card.Header>
77
- <Card.Footer>
78
- <Button>Deploy</Button>
79
- </Card.Footer>
80
- </Card>
116
+ <ThemeProvider value={colorScheme === 'dark' ? DarkTheme : DefaultTheme}>
117
+ <AppTabs />
118
+ </ThemeProvider>
81
119
  </PanelUIProvider>
82
120
  );
83
121
  }
84
122
  ```
85
123
 
124
+ That navigation theme paints over PanelUI's background once you switch themes — see
125
+ [Using Expo Router?](#using-expo-router-read-this) below for the version fed from live tokens.
126
+
86
127
  `PanelUIProvider` sets up the gesture root, the themed page background, the portal host used by
87
- overlays, and the toast viewport.
128
+ overlays, and the toast viewport. One at the root is enough — don't nest a second.
129
+
130
+ You do **not** need a `babel.config.js`; Expo's default preset already wires the worklets plugin
131
+ Reanimated needs.
132
+
133
+ ### 5. Restart
134
+
135
+ ```sh
136
+ npx expo start --clear
137
+ ```
138
+
139
+ Metro reads `metro.config.js`, `global.css` and `extraThemes` once, at startup. After changing any
140
+ of them, stop the dev server and start it again — `--clear` on a running one is not enough.
141
+
142
+ ```tsx
143
+ import { Button, Card } from 'panelui-native';
144
+
145
+ <Card>
146
+ <Card.Header>
147
+ <Card.Title>It works</Card.Title>
148
+ <Card.Description>PanelUI is installed and themed.</Card.Description>
149
+ </Card.Header>
150
+ <Card.Footer>
151
+ <Button>Deploy</Button>
152
+ </Card.Footer>
153
+ </Card>;
154
+ ```
155
+
156
+ A themed background, a card with a border and radius, and a button that dips when pressed means
157
+ you are done. Unstyled text on a white screen means the styles are not reaching the bundle — see
158
+ [Troubleshooting](https://panelui.dev/docs/installation#troubleshooting).
88
159
 
89
160
  ## Components
90
161
 
@@ -246,6 +317,25 @@ the named themes, which the OS `Appearance` API knows nothing about. For the sam
246
317
 
247
318
  ## FAQ
248
319
 
320
+ ### The first bundle fails with `Unable to resolve module …`
321
+
322
+ A required package is missing. Run the [install command](#1-install-the-packages) again — all of
323
+ it, not just the package named in the error. Metro resolves every import in the library, so this
324
+ happens even for components you never use.
325
+
326
+ ### `Cannot use @variant with unknown variant: moon` when building
327
+
328
+ Fixed in 0.22.5 — upgrade with `npx expo install panelui-native`. Before that release the Moon and
329
+ Grass token blocks leaned on variants that only existed in the artifact Uniwind generates from your
330
+ Metro config, so the dev server worked while `npx expo export` and EAS builds failed.
331
+
332
+ ### None of my classes do anything
333
+
334
+ In order of likelihood: `metro.config.js` is not in the project root; it does not wrap the config
335
+ in `withUniwindConfig`; `cssEntryFile` does not point at your CSS file; `import './global.css'` is
336
+ missing from the entry file; or the dev server was running when you changed one of those. Full
337
+ list at [Troubleshooting](https://panelui.dev/docs/installation#troubleshooting).
338
+
249
339
  ### How is PanelUI different from NativeWind?
250
340
 
251
341
  NativeWind is a styling engine; PanelUI is a component library. PanelUI is built on **Uniwind**,
@@ -52,21 +52,31 @@ const inputVariants = tv({
52
52
  }
53
53
  },
54
54
  size: {
55
+ /*
56
+ * The font size is given as a length rather than through a `text-*`
57
+ * step, because those set a size and a line height together — 16px text
58
+ * in a 24px line box. The extra leading lands above the glyphs, so in a
59
+ * field of fixed height the text and the placeholder end up sitting
60
+ * below the middle of the box, a few pixels off whatever is beside them.
61
+ * A length sets the size alone and leaves the line box the font's own.
62
+ */
55
63
  sm: {
56
- field: 'h-10 px-3 text-sm'
64
+ field: 'h-10 px-3 text-[14px]'
57
65
  },
58
66
  md: {
59
- field: 'h-12 px-3.5 text-base'
67
+ field: 'h-12 px-3.5 text-[16px]'
60
68
  },
61
69
  lg: {
62
- field: 'h-14 px-4 text-base'
70
+ field: 'h-14 px-4 text-[16px]'
63
71
  }
64
72
  },
65
73
  multiline: {
66
74
  // A multiline field grows, so a fixed height would crop it. Text starts
67
- // at the top rather than floating in the middle of an empty box.
75
+ // at the top rather than floating in the middle of an empty box — and
76
+ // once there are several lines the leading is wanted back, since here it
77
+ // separates the lines instead of pushing one off centre.
68
78
  true: {
69
- field: 'h-auto min-h-24 py-3'
79
+ field: 'h-auto min-h-24 py-3 leading-normal'
70
80
  }
71
81
  },
72
82
  disabled: {
@@ -1 +1 @@
1
- {"version":3,"names":["forwardRef","useCallback","useEffect","useState","TextInput","View","Animated","interpolateColor","useAnimatedStyle","useSharedValue","withTiming","tv","useCSSVariable","KeyboardAvoider","Text","Label","jsx","_jsx","Fragment","_Fragment","jsxs","_jsxs","FOCUS_DURATION","inputVariants","slots","container","field","description","error","variants","variant","outline","filled","size","sm","md","lg","multiline","true","disabled","defaultVariants","AnimatedTextInput","createAnimatedComponent","Input","className","containerClassName","label","errorMessage","isRequired","avoidKeyboard","keyboardMode","keyboardOffset","keyboardBottomInset","onFocus","onBlur","style","props","ref","focused","setFocused","invalid","placeholderColor","restColor","focusColor","errorColor","focus","value","duration","resting","active","idle","borderStyle","borderColor","handleFocus","event","handleBlur","body","children","isInvalid","isDisabled","editable","accessibilityLabel","accessibilityState","placeholderTextColor","undefined","containerClasses","mode","offset","bottomInset","displayName"],"sourceRoot":"../../../../src","sources":["components/input/index.tsx"],"mappings":"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","ignoreList":[]}
1
+ {"version":3,"names":["forwardRef","useCallback","useEffect","useState","TextInput","View","Animated","interpolateColor","useAnimatedStyle","useSharedValue","withTiming","tv","useCSSVariable","KeyboardAvoider","Text","Label","jsx","_jsx","Fragment","_Fragment","jsxs","_jsxs","FOCUS_DURATION","inputVariants","slots","container","field","description","error","variants","variant","outline","filled","size","sm","md","lg","multiline","true","disabled","defaultVariants","AnimatedTextInput","createAnimatedComponent","Input","className","containerClassName","label","errorMessage","isRequired","avoidKeyboard","keyboardMode","keyboardOffset","keyboardBottomInset","onFocus","onBlur","style","props","ref","focused","setFocused","invalid","placeholderColor","restColor","focusColor","errorColor","focus","value","duration","resting","active","idle","borderStyle","borderColor","handleFocus","event","handleBlur","body","children","isInvalid","isDisabled","editable","accessibilityLabel","accessibilityState","placeholderTextColor","undefined","containerClasses","mode","offset","bottomInset","displayName"],"sourceRoot":"../../../../src","sources":["components/input/index.tsx"],"mappings":"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","ignoreList":[]}
@@ -0,0 +1,350 @@
1
+ "use strict";
2
+
3
+ /**
4
+ * NumberInput — a value stepped by two buttons or typed by hand.
5
+ *
6
+ * A number is not a slider: past a handful of steps, dragging to 47 is worse
7
+ * than tapping + a few times or just typing it. So the control keeps both
8
+ * doors open — a − and a + at the ends for nudging, and an editable field in
9
+ * the middle for jumping straight to a value — and reconciles them through a
10
+ * single clamped, step-snapped number.
11
+ *
12
+ * The two ends are not just tap targets. Hold one down and it repeats, after a
13
+ * short delay and then faster, the way a native stepper does — so walking from
14
+ * 0 to 200 is a press, not two hundred of them. The repeat reads the live
15
+ * value from a ref rather than a closure, so it never strides off a stale
16
+ * number.
17
+ *
18
+ * Typing is allowed to be briefly invalid — an empty field, a lone `-`, a
19
+ * trailing `.` — because clamping every keystroke fights the person mid-number.
20
+ * The field commits (parses, snaps, clamps) on blur, and falls back to the
21
+ * last good value when what is left cannot be read as a number.
22
+ *
23
+ * ```tsx
24
+ * <NumberInput defaultValue={1} min={0} max={10} />
25
+ * <NumberInput label="Quantity" value={qty} onValueChange={setQty} />
26
+ * ```
27
+ *
28
+ * Runs controlled (`value` + `onValueChange`) or uncontrolled (`defaultValue`).
29
+ */
30
+ import { forwardRef, useCallback, useEffect, useRef, useState } from 'react';
31
+ import { TextInput, View } from 'react-native';
32
+ import { tv } from 'tailwind-variants';
33
+ import { useCSSVariable } from 'uniwind';
34
+ import { MinusIcon, PlusIcon } from "../../icons/index.js";
35
+ import { AnimatedPressable } from "../../primitives/animated-pressable.js";
36
+ import { Text } from "../../primitives/text.js";
37
+ import { selectionTick } from "../../utils/haptics.js";
38
+ import { Label } from "../label/index.js";
39
+
40
+ /** Wait before a held button starts repeating — a tap must not trip it. */
41
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
42
+ const REPEAT_DELAY = 400;
43
+ /** Interval between repeats once holding — fast enough to cover ground. */
44
+ const REPEAT_INTERVAL = 80;
45
+ const numberInputVariants = tv({
46
+ slots: {
47
+ container: 'w-full gap-1.5',
48
+ control: 'w-full flex-row items-center overflow-hidden rounded-lg border',
49
+ button: 'h-full items-center justify-center',
50
+ // The field takes the full height so the digits centre against the same
51
+ // box the two glyphs do, rather than against their own line's height.
52
+ field: 'h-full flex-1 text-center font-medium text-foreground',
53
+ description: 'text-sm text-muted-foreground',
54
+ error: 'text-sm text-destructive'
55
+ },
56
+ variants: {
57
+ variant: {
58
+ // Matches Input: outline draws its own edge on the page; filled sits
59
+ // inside a card, where a second border reads as a seam.
60
+ outline: {
61
+ control: 'border-input bg-background'
62
+ },
63
+ filled: {
64
+ control: 'border-transparent bg-muted'
65
+ }
66
+ },
67
+ size: {
68
+ sm: {
69
+ control: 'h-10',
70
+ button: 'w-10'
71
+ },
72
+ md: {
73
+ control: 'h-12',
74
+ button: 'w-12'
75
+ },
76
+ lg: {
77
+ control: 'h-14',
78
+ button: 'w-14'
79
+ }
80
+ },
81
+ invalid: {
82
+ true: {
83
+ control: 'border-destructive'
84
+ }
85
+ },
86
+ disabled: {
87
+ true: {
88
+ container: 'opacity-[0.64]'
89
+ }
90
+ }
91
+ },
92
+ defaultVariants: {
93
+ variant: 'outline',
94
+ size: 'md'
95
+ }
96
+ });
97
+
98
+ /** Icon size per control size — the glyph scales with its target. */
99
+ const ICON_SIZE = {
100
+ sm: 16,
101
+ md: 18,
102
+ lg: 20
103
+ };
104
+
105
+ /**
106
+ * The field's job is not to be a box of its own: it has to put the number on
107
+ * exactly the axis the − and the + sit on, and in the exact middle between
108
+ * them. An editable field does not do that unhelped — it arrives with padding
109
+ * and, on Android, with font padding above and below the line, all of which
110
+ * shift the digits off centre. Zeroing both and centring the line in the full
111
+ * height leaves geometry as the only thing placing the number.
112
+ *
113
+ * Tabular figures on top of that, so the digits keep the same advance widths
114
+ * while the value counts — a 1 that is narrower than a 7 makes a centred
115
+ * number appear to shuffle sideways as it steps.
116
+ */
117
+ const FIELD_BASE = {
118
+ paddingVertical: 0,
119
+ paddingHorizontal: 0,
120
+ includeFontPadding: false,
121
+ textAlignVertical: 'center',
122
+ fontVariant: ['tabular-nums']
123
+ };
124
+
125
+ /**
126
+ * Font size is set here rather than by a text class because those bring a line
127
+ * height with them: a 16px number in a 24px line box. The extra leading is
128
+ * added above the digits, so centring that box leaves the number sitting a
129
+ * couple of pixels below the − and the + it is meant to line up with — close
130
+ * enough to look like a mistake rather than a difference. Sized this way the
131
+ * line box is the font's own, and centring it centres the digits.
132
+ */
133
+ const FIELD_STYLE = {
134
+ sm: {
135
+ ...FIELD_BASE,
136
+ fontSize: 14
137
+ },
138
+ md: {
139
+ ...FIELD_BASE,
140
+ fontSize: 16
141
+ },
142
+ lg: {
143
+ ...FIELD_BASE,
144
+ fontSize: 16
145
+ }
146
+ };
147
+ /** Decimals implied by `step`, so display and math round to the same place. */
148
+ function precisionOf(step) {
149
+ if (!isFinite(step)) return 0;
150
+ const s = String(step);
151
+ const dot = s.indexOf('.');
152
+ return dot === -1 ? 0 : s.length - dot - 1;
153
+ }
154
+ function clamp(value, min, max) {
155
+ return Math.min(Math.max(value, min), max);
156
+ }
157
+
158
+ /**
159
+ * Snaps to the nearest step from a finite base (or 0 when `min` is open), then
160
+ * rounds to the step's precision so 0.1 + 0.2 does not drift to 0.30000004.
161
+ */
162
+ function normalize(value, min, max, step) {
163
+ const base = isFinite(min) ? min : 0;
164
+ const snapped = isFinite(step) && step > 0 ? Math.round((value - base) / step) * step + base : value;
165
+ const p = precisionOf(step);
166
+ const factor = 10 ** p;
167
+ return clamp(Math.round(snapped * factor) / factor, min, max);
168
+ }
169
+
170
+ /**
171
+ * A number stepped by buttons or typed by hand, reconciled to one clamped,
172
+ * step-snapped value. See the file header for why it keeps both affordances.
173
+ */
174
+ export const NumberInput = /*#__PURE__*/forwardRef(({
175
+ className,
176
+ containerClassName,
177
+ value: controlledValue,
178
+ defaultValue,
179
+ min = -Infinity,
180
+ max = Infinity,
181
+ step = 1,
182
+ onValueChange,
183
+ formatValue,
184
+ editable = true,
185
+ variant = 'outline',
186
+ size = 'md',
187
+ disabled,
188
+ label,
189
+ description,
190
+ errorMessage,
191
+ isRequired,
192
+ haptics,
193
+ placeholder,
194
+ onFocus,
195
+ onBlur,
196
+ returnKeyType
197
+ }, ref) => {
198
+ const isControlled = controlledValue !== undefined;
199
+ const initial = normalize(controlledValue ?? defaultValue ?? (isFinite(min) ? min : 0), min, max, step);
200
+ const [uncontrolled, setUncontrolled] = useState(initial);
201
+ const value = isControlled ? normalize(controlledValue, min, max, step) : uncontrolled;
202
+
203
+ // The repeat timers read the live value through a ref, so a held button
204
+ // keeps counting from where it is rather than from the value it closed over.
205
+ const valueRef = useRef(value);
206
+ valueRef.current = value;
207
+ const invalid = !!errorMessage;
208
+ const foreground = useCSSVariable('--color-foreground');
209
+ const iconColor = typeof foreground === 'string' ? foreground : undefined;
210
+ const slots = numberInputVariants({
211
+ variant,
212
+ size,
213
+ invalid,
214
+ disabled: !!disabled
215
+ });
216
+ const format = useCallback(v => formatValue ? formatValue(v) : String(v), [formatValue]);
217
+
218
+ // `text` is what the field shows while focused; it is allowed to be
219
+ // half-typed. Away from focus it always mirrors the committed value.
220
+ const [text, setText] = useState(() => format(value));
221
+ const [focused, setFocused] = useState(false);
222
+ useEffect(() => {
223
+ if (!focused) setText(format(value));
224
+ }, [value, focused, format]);
225
+ const commit = useCallback((next, tick) => {
226
+ const clamped = normalize(next, min, max, step);
227
+ if (tick && haptics) selectionTick();
228
+ if (!isControlled) setUncontrolled(clamped);
229
+ if (clamped !== value) onValueChange?.(clamped);
230
+ }, [min, max, step, haptics, isControlled, value, onValueChange]);
231
+
232
+ // --- hold-to-repeat -----------------------------------------------------
233
+ const delayRef = useRef(null);
234
+ const intervalRef = useRef(null);
235
+ const stopRepeat = useCallback(() => {
236
+ if (delayRef.current) clearTimeout(delayRef.current);
237
+ if (intervalRef.current) clearInterval(intervalRef.current);
238
+ delayRef.current = null;
239
+ intervalRef.current = null;
240
+ }, []);
241
+ useEffect(() => stopRepeat, [stopRepeat]);
242
+ const startRepeat = useCallback(direction => {
243
+ const nudge = () => commit(valueRef.current + direction * step, true);
244
+ nudge();
245
+ delayRef.current = setTimeout(() => {
246
+ intervalRef.current = setInterval(nudge, REPEAT_INTERVAL);
247
+ }, REPEAT_DELAY);
248
+ }, [commit, step]);
249
+ const atMin = value <= min;
250
+ const atMax = value >= max;
251
+ const handleEndEditing = useCallback(() => {
252
+ const parsed = parseFloat(text);
253
+ // An empty or unreadable field falls back to the last good value rather
254
+ // than snapping to a surprising 0.
255
+ commit(Number.isNaN(parsed) ? value : parsed, false);
256
+ setFocused(false);
257
+ setText(format(Number.isNaN(parsed) ? value : normalize(parsed, min, max, step)));
258
+ }, [text, value, commit, format, min, max, step]);
259
+ return /*#__PURE__*/_jsxs(View, {
260
+ className: slots.container({
261
+ className: containerClassName
262
+ }),
263
+ children: [label ? /*#__PURE__*/_jsx(Label, {
264
+ isRequired: isRequired,
265
+ isInvalid: invalid,
266
+ isDisabled: !!disabled,
267
+ children: label
268
+ }) : null, /*#__PURE__*/_jsxs(View, {
269
+ className: slots.control({
270
+ className
271
+ }),
272
+ children: [/*#__PURE__*/_jsx(AnimatedPressable, {
273
+ className: slots.button(),
274
+ disabled: disabled || atMin,
275
+ pressOpacity: 0.6,
276
+ onPressIn: () => {
277
+ if (!disabled && !atMin) startRepeat(-1);
278
+ },
279
+ onPressOut: stopRepeat,
280
+ accessibilityRole: "button",
281
+ accessibilityLabel: `Decrease ${label ?? 'value'}`,
282
+ accessibilityState: {
283
+ disabled: disabled || atMin
284
+ },
285
+ style: atMin ? {
286
+ opacity: 0.4
287
+ } : undefined,
288
+ children: /*#__PURE__*/_jsx(MinusIcon, {
289
+ size: ICON_SIZE[size],
290
+ color: iconColor,
291
+ strokeWidth: 2
292
+ })
293
+ }), /*#__PURE__*/_jsx(TextInput, {
294
+ ref: ref,
295
+ editable: editable && !disabled,
296
+ value: text,
297
+ keyboardType: precisionOf(step) > 0 ? 'decimal-pad' : 'number-pad',
298
+ placeholder: placeholder,
299
+ returnKeyType: returnKeyType,
300
+ selectTextOnFocus: true,
301
+ onChangeText: setText,
302
+ onFocus: e => {
303
+ setFocused(true);
304
+ onFocus?.(e);
305
+ },
306
+ onBlur: e => {
307
+ handleEndEditing();
308
+ onBlur?.(e);
309
+ },
310
+ onSubmitEditing: handleEndEditing,
311
+ accessibilityLabel: label,
312
+ accessibilityState: {
313
+ disabled: !!disabled
314
+ },
315
+ "aria-required": isRequired,
316
+ "aria-invalid": invalid,
317
+ className: slots.field(),
318
+ style: FIELD_STYLE[size]
319
+ }), /*#__PURE__*/_jsx(AnimatedPressable, {
320
+ className: slots.button(),
321
+ disabled: disabled || atMax,
322
+ pressOpacity: 0.6,
323
+ onPressIn: () => {
324
+ if (!disabled && !atMax) startRepeat(1);
325
+ },
326
+ onPressOut: stopRepeat,
327
+ accessibilityRole: "button",
328
+ accessibilityLabel: `Increase ${label ?? 'value'}`,
329
+ accessibilityState: {
330
+ disabled: disabled || atMax
331
+ },
332
+ style: atMax ? {
333
+ opacity: 0.4
334
+ } : undefined,
335
+ children: /*#__PURE__*/_jsx(PlusIcon, {
336
+ size: ICON_SIZE[size],
337
+ color: iconColor
338
+ })
339
+ })]
340
+ }), errorMessage ? /*#__PURE__*/_jsx(Text, {
341
+ className: slots.error(),
342
+ children: errorMessage
343
+ }) : description ? /*#__PURE__*/_jsx(Text, {
344
+ className: slots.description(),
345
+ children: description
346
+ }) : null]
347
+ });
348
+ });
349
+ NumberInput.displayName = 'NumberInput';
350
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"names":["forwardRef","useCallback","useEffect","useRef","useState","TextInput","View","tv","useCSSVariable","MinusIcon","PlusIcon","AnimatedPressable","Text","selectionTick","Label","jsx","_jsx","jsxs","_jsxs","REPEAT_DELAY","REPEAT_INTERVAL","numberInputVariants","slots","container","control","button","field","description","error","variants","variant","outline","filled","size","sm","md","lg","invalid","true","disabled","defaultVariants","ICON_SIZE","FIELD_BASE","paddingVertical","paddingHorizontal","includeFontPadding","textAlignVertical","fontVariant","FIELD_STYLE","fontSize","precisionOf","step","isFinite","s","String","dot","indexOf","length","clamp","value","min","max","Math","normalize","base","snapped","round","p","factor","NumberInput","className","containerClassName","controlledValue","defaultValue","Infinity","onValueChange","formatValue","editable","label","errorMessage","isRequired","haptics","placeholder","onFocus","onBlur","returnKeyType","ref","isControlled","undefined","initial","uncontrolled","setUncontrolled","valueRef","current","foreground","iconColor","format","v","text","setText","focused","setFocused","commit","next","tick","clamped","delayRef","intervalRef","stopRepeat","clearTimeout","clearInterval","startRepeat","direction","nudge","setTimeout","setInterval","atMin","atMax","handleEndEditing","parsed","parseFloat","Number","isNaN","children","isInvalid","isDisabled","pressOpacity","onPressIn","onPressOut","accessibilityRole","accessibilityLabel","accessibilityState","style","opacity","color","strokeWidth","keyboardType","selectTextOnFocus","onChangeText","e","onSubmitEditing","displayName"],"sourceRoot":"../../../../src","sources":["components/number-input/index.tsx"],"mappings":"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","ignoreList":[]}
@@ -5,6 +5,7 @@ import { Pressable, View } from 'react-native';
5
5
  import Animated, { interpolate, useAnimatedStyle, useSharedValue, withSpring } from 'react-native-reanimated';
6
6
  import { tv } from 'tailwind-variants';
7
7
  import { getNativeUI } from "../../native/index.js";
8
+ import { selectionTick } from "../../utils/haptics.js";
8
9
  import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
9
10
  const SPRING = {
10
11
  damping: 18,
@@ -53,7 +54,8 @@ export const Switch = /*#__PURE__*/forwardRef(({
53
54
  disabled,
54
55
  size = 'md',
55
56
  native,
56
- label
57
+ label,
58
+ haptics
57
59
  }, ref) => {
58
60
  const progress = useSharedValue(value ? 1 : 0);
59
61
  const nativeUI = native ? getNativeUI() : null;
@@ -102,7 +104,10 @@ export const Switch = /*#__PURE__*/forwardRef(({
102
104
  disabled: !!disabled
103
105
  },
104
106
  disabled: disabled,
105
- onPress: () => onValueChange?.(!value),
107
+ onPress: () => {
108
+ if (haptics) selectionTick();
109
+ onValueChange?.(!value);
110
+ },
106
111
  hitSlop: 8,
107
112
  children: /*#__PURE__*/_jsxs(View, {
108
113
  className: slots.track({