{
  "$schema": "https://ui.shadcn.com/schema/registry-item.json",
  "name": "glass-input",
  "title": "Glass Input",
  "description": "A recessed glass text field with a label and an optional hint.",
  "registryDependencies": [
    "@glassyui-native/glass-provider"
  ],
  "files": [
    {
      "path": "registry/glassyui-native/glass-input.tsx",
      "content": "import { forwardRef, useCallback, useState } from 'react';\nimport {\n  StyleSheet,\n  Text,\n  TextInput,\n  View,\n  type BlurEvent,\n  type FocusEvent,\n  type TextInputProps,\n} from 'react-native';\nimport { useGlassTheme } from './glass-provider';\nimport { GLASS_RADIUS } from './lib/tokens';\n\nexport type GlassInputProps = TextInputProps & {\n  /** A line of muted text under the field. With `invalid` it turns the invalid colour. */\n  hint?: string;\n  /** Marks the value as wrong: the field's ring and its hint turn the invalid colour. */\n  invalid?: boolean;\n  /** Text above the field. It also names the field for screen readers. */\n  label?: string;\n};\n\n// The recessed well a field sits in, from --lg-input-shadow.\nconst WELL_SHADOW = {\n  dark: 'inset 0px 1px 2px rgba(0, 0, 0, 0.24), inset 0px -1px 0px rgba(255, 255, 255, 0.06)',\n  light: 'inset 0px 1px 2px rgba(0, 0, 0, 0.08), inset 0px -1px 0px rgba(255, 255, 255, 0.8)',\n} as const;\n\n// A focused field lightens, as --lg-control-surface-hover does.\nconst FOCUSED_FILL = {\n  dark: 'rgba(245, 245, 247, 0.14)',\n  light: 'rgba(255, 255, 255, 0.95)',\n} as const;\n\n// The theme's muted ink at the web's 72%, so a placeholder reads as a placeholder.\nconst PLACEHOLDER = {\n  dark: 'rgba(209, 209, 214, 0.72)',\n  light: 'rgba(80, 80, 85, 0.72)',\n} as const;\n\n/**\n * A recessed text field with an optional label above and hint below. It rings in the focus\n * colour while focused and in the invalid colour while `invalid`; `editable={false}` dims it.\n */\nexport const GlassInput = forwardRef<TextInput, GlassInputProps>(\n  ({ editable = true, hint, invalid = false, label, onBlur, onFocus, style, ...rest }, ref) => {\n    const { colors, preferences } = useGlassTheme();\n    const [focused, setFocused] = useState(false);\n    const theme = preferences.theme;\n    const ring = invalid ? colors.invalid : focused ? colors.focusRing : null;\n\n    const handleFocus = useCallback(\n      (event: FocusEvent) => {\n        setFocused(true);\n        onFocus?.(event);\n      },\n      [onFocus],\n    );\n\n    const handleBlur = useCallback(\n      (event: BlurEvent) => {\n        setFocused(false);\n        onBlur?.(event);\n      },\n      [onBlur],\n    );\n\n    // The field carries the label and hint for screen readers, so the visible text is hidden\n    // from them rather than read twice.\n    return (\n      <View style={styles.field}>\n        {label ? (\n          <Text\n            accessibilityElementsHidden\n            importantForAccessibility=\"no\"\n            style={[styles.label, { color: colors.mutedForeground }]}\n          >\n            {label}\n          </Text>\n        ) : null}\n        <TextInput\n          ref={ref}\n          accessibilityHint={hint}\n          accessibilityLabel={label}\n          accessibilityState={{ disabled: !editable }}\n          editable={editable}\n          onBlur={handleBlur}\n          onFocus={handleFocus}\n          placeholderTextColor={PLACEHOLDER[theme]}\n          underlineColorAndroid=\"transparent\"\n          style={[\n            styles.input,\n            {\n              backgroundColor: focused ? FOCUSED_FILL[theme] : colors.controlSurface,\n              borderColor: ring ?? colors.border,\n              boxShadow: ring ? `0px 0px 0px 1px ${ring}` : WELL_SHADOW[theme],\n              color: colors.foreground,\n            },\n            !editable && styles.disabled,\n            style,\n          ]}\n          {...rest}\n        />\n        {hint ? (\n          <Text\n            accessibilityElementsHidden\n            importantForAccessibility=\"no\"\n            style={[styles.hint, { color: invalid ? colors.invalid : colors.mutedForeground }]}\n          >\n            {hint}\n          </Text>\n        ) : null}\n      </View>\n    );\n  },\n);\n\nGlassInput.displayName = 'GlassInput';\n\nconst styles = StyleSheet.create({\n  disabled: { opacity: 0.45 },\n  field: { alignSelf: 'stretch', gap: 8 },\n  hint: { fontSize: 12, lineHeight: 16 },\n  input: {\n    borderCurve: 'continuous',\n    borderRadius: GLASS_RADIUS.md,\n    borderWidth: 1,\n    fontSize: 16,\n    minHeight: 44,\n    paddingHorizontal: 20,\n    paddingVertical: 14,\n  },\n  label: { fontSize: 14, fontWeight: '500', lineHeight: 20 },\n});\n",
      "type": "registry:ui",
      "target": "components/glassyui/glass-input.tsx"
    }
  ],
  "type": "registry:ui"
}