{
  "$schema": "https://ui.shadcn.com/schema/registry-item.json",
  "name": "numeric-keypad",
  "title": "Numeric keypad",
  "description": "3×4 in-app keypad, keys on `bg-muted`",
  "dependencies": [
    "lucide-react-native@^1.21.0"
  ],
  "registryDependencies": [
    "@kit-native/icon",
    "@kit-native/lib-haptics",
    "@kit-native/lib-utils",
    "@kit-native/text"
  ],
  "files": [
    {
      "path": "components/kit/numeric-keypad.tsx",
      "content": "import { Icon } from '@/components/ui/icon';\nimport { Text } from '@/components/ui/text';\nimport { haptic } from '@/lib/haptics';\nimport { cn } from '@/lib/utils';\nimport { DeleteIcon } from 'lucide-react-native';\nimport * as React from 'react';\nimport { type LayoutChangeEvent, Pressable, View } from 'react-native';\n\ntype Props = {\n  value: string;\n  onChange: (next: string) => void;\n  maxLength?: number;\n  allowDecimal?: boolean;\n  disabled?: boolean;\n  className?: string;\n};\n\nconst GAP = 10;\nconst ROWS = [\n  ['1', '2', '3'],\n  ['4', '5', '6'],\n  ['7', '8', '9'],\n] as const;\n\n/**\n * In-app 3×4 keypad for full-screen amount entry (pair with AmountInput editable={false}).\n * Keys get an explicit measured width: three flex children in a gapped row don't distribute\n * reliably on iOS.\n */\nexport function NumericKeypad({ value, onChange, maxLength = 12, allowDecimal = true, disabled, className }: Props) {\n  const [rowW, setRowW] = React.useState(0);\n  const keyW = rowW > 0 ? (rowW - GAP * 2) / 3 : 0;\n\n  const digit = (d: string) => {\n    if (disabled || value.length >= maxLength) return;\n    haptic('selection');\n    onChange(value === '0' ? d : value + d);\n  };\n  const decimal = () => {\n    if (disabled || !allowDecimal || value.includes('.') || value.length >= maxLength) return;\n    haptic('selection');\n    onChange(value === '' ? '0.' : value + '.');\n  };\n  const backspace = () => {\n    if (disabled || value === '') return;\n    haptic('light');\n    onChange(value.slice(0, -1));\n  };\n  const clear = () => {\n    if (disabled) return;\n    haptic('medium');\n    onChange('');\n  };\n  const onRowLayout = (e: LayoutChangeEvent) => {\n    const w = e.nativeEvent.layout.width;\n    if (w > 0 && w !== rowW) setRowW(w);\n  };\n\n  return (\n    <View className={cn('self-stretch', disabled && 'opacity-50', className)} style={{ gap: GAP }}>\n      {ROWS.map((row, i) => (\n        <View key={i} onLayout={i === 0 ? onRowLayout : undefined} className=\"flex-row justify-between\">\n          {row.map((d) => (\n            <Key key={d} label={d} width={keyW} onPress={() => digit(d)} />\n          ))}\n        </View>\n      ))}\n      <View className=\"flex-row justify-between\">\n        {allowDecimal ? <Key label=\".\" width={keyW} onPress={decimal} /> : <View style={{ width: keyW || undefined, flex: keyW ? undefined : 1 }} />}\n        <Key label=\"0\" width={keyW} onPress={() => digit('0')} />\n        <Key width={keyW} onPress={backspace} onLongPress={clear} accessibilityLabel=\"Backspace\">\n          <Icon as={DeleteIcon} size={22} />\n        </Key>\n      </View>\n    </View>\n  );\n}\n\nfunction Key({\n  label,\n  width,\n  onPress,\n  onLongPress,\n  accessibilityLabel,\n  children,\n}: {\n  label?: string;\n  width: number;\n  onPress: () => void;\n  onLongPress?: () => void;\n  accessibilityLabel?: string;\n  children?: React.ReactNode;\n}) {\n  return (\n    <Pressable\n      accessibilityRole=\"button\"\n      accessibilityLabel={accessibilityLabel ?? label}\n      onPress={onPress}\n      onLongPress={onLongPress}\n      className=\"bg-muted h-14 items-center justify-center rounded-lg active:opacity-60\"\n      style={{ width: width || undefined, flex: width ? undefined : 1 }}>\n      {children ?? <Text className=\"text-2xl font-medium\">{label}</Text>}\n    </Pressable>\n  );\n}\n",
      "type": "registry:component",
      "target": "components/kit/numeric-keypad.tsx"
    }
  ],
  "meta": {
    "exports": [
      "NumericKeypad"
    ],
    "api": "<NumericKeypad value onChange maxLength? allowDecimal? />"
  },
  "docs": "Run `npx expo install --fix` afterwards so Expo SDK packages match your SDK. Needs the kit theme (`@kit-native/theme`) and `KitThemeProvider` from `@kit-native/lib-theme-context` at the root.",
  "categories": [
    "inputs"
  ],
  "type": "registry:component"
}