Files
zeekayandHanzo Dev 751ef5c778 rename the framework to @hanzo/gui and the loader to @hanzogui/loader
Both old names are owned by a different npm account (artemis-prime), so
publishing them returns 403 — which is how this surfaced: the 8.0.0 run
shipped @hanzogui/logo and @hanzogui/demos depending on [email protected], a
version that cannot be published and therefore does not exist. Those two
were uninstallable.

@hanzo/gui and @hanzogui/* are ours, so the framework now carries the name
it is imported by everywhere downstream, and the loader moves under the
scope we control.

The rewrite is limited to package references. `DEBUG?.startsWith('hanzogui')`
is a log-namespace filter and join(dir, 'hanzogui') is a path — rewriting
either would change behaviour, so both are untouched.

Co-authored-by: Hanzo Dev <[email protected]>
2026-07-30 20:23:18 -07:00

331 lines
7.9 KiB
Plaintext

---
title: Input & TextArea
description: Single-line and multi-line text inputs with web-first API
name: inputs
component: Input
package: input
demoName: Inputs
---
<HeroContainer demoMultiple>
<NewInputsDemo />
</HeroContainer>
```tsx hero template=Inputs
```
The v2 Input uses web-standard HTML APIs as the primary interface, with automatic conversion to React Native equivalents on native platforms. This means you write web-first code that works everywhere.
## Installation
Input is already installed in `hanzogui`, or you can install it independently:
```bash
npm install @hanzogui/input
```
## Usage
A single-line text input:
```tsx
import { Input } from '@hanzo/gui'
export default () => <Input placeholder="Enter text..." size="$4" />
```
For multi-line text input, use `TextArea`:
```tsx
import { TextArea } from '@hanzo/gui'
export default () => <TextArea placeholder="Enter long text..." rows={4} />
```
## Web-First API
The v2 Input uses standard HTML input attributes. Here are the key props:
### Input Types
Use the standard HTML `type` attribute. On native, these automatically map to the appropriate keyboard and behavior:
```tsx
// Password input
<Input type="password" />
// Email input (shows email keyboard on native)
<Input type="email" />
// Phone number (shows phone pad on native)
<Input type="tel" />
// Number input (shows numeric keyboard on native)
<Input type="number" />
// URL input
<Input type="url" />
// Search input
<Input type="search" />
```
**Cross-platform mapping:**
| Web `type` | Native behavior |
| ---------- | ------------------------------ |
| `password` | `secureTextEntry={true}` |
| `email` | `keyboardType="email-address"` |
| `tel` | `keyboardType="phone-pad"` |
| `number` | `keyboardType="numeric"` |
| `url` | `keyboardType="url"` |
| `search` | `inputMode="search"` |
### Enter Key Behavior
Use `enterKeyHint` to control the enter/return key label on virtual keyboards:
```tsx
<Input enterKeyHint="search" />
<Input enterKeyHint="send" />
<Input enterKeyHint="done" />
<Input enterKeyHint="go" />
<Input enterKeyHint="next" />
```
On native, this automatically maps to `returnKeyType`.
### Form Attributes
Standard HTML form attributes work as expected:
```tsx
<Input
name="email"
placeholder="Enter email"
required
maxLength={100}
minLength={3}
pattern="[a-z@.]+"
autoComplete="email"
autoFocus
readOnly={false}
disabled={false}
/>
```
### Events
Use standard web events:
```tsx
<Input
onChange={(e) => console.log(e.target.value)}
onFocus={(e) => console.log('focused')}
onBlur={(e) => console.log('blurred')}
onKeyDown={(e) => {
if (e.key === 'Enter') {
// handle enter
}
}}
/>
```
For convenience, `onChangeText` is still supported but deprecated:
```tsx
// Deprecated - use onChange instead
<Input onChangeText={(text) => setText(text)} />
// Preferred
<Input onChange={(e) => setText(e.target.value)} />
```
### Submit Handling
For handling form submission on enter:
```tsx
<Input
onSubmitEditing={(e) => {
console.log('Submitted:', e.nativeEvent.text)
}}
/>
```
## Styling
Input accepts all Gui style props and supports the `size` prop for consistent scaling:
```tsx
<Input
size="$4"
borderWidth={2}
borderColor="$borderColor"
borderRadius="$4"
backgroundColor="$background"
color="$color"
placeholderTextColor="$placeholderColor"
selectionColor="$accentColor"
hoverStyle={{
borderColor: '$borderColorHover',
}}
focusStyle={{
borderColor: '$borderColorFocus',
}}
/>
```
## Native-Only Props
Some props only apply on native platforms and have no web equivalent:
**keyboardAppearance (iOS)**: Controls the keyboard color scheme on iOS:
```tsx
<Input keyboardAppearance="dark" />
<Input keyboardAppearance="light" />
<Input keyboardAppearance="default" />
```
**textContentType (iOS)**: Provides hints for iOS autofill:
```tsx
<Input textContentType="emailAddress" />
<Input textContentType="password" />
<Input textContentType="newPassword" />
<Input textContentType="oneTimeCode" />
<Input textContentType="telephoneNumber" />
<Input textContentType="username" />
```
For web autofill, use the standard `autoComplete` attribute instead.
## Cross-Platform Text Behavior
These props work on both web and native with automatic value conversion:
### autoCorrect
Controls automatic spelling correction:
```tsx
// Boolean values (work everywhere)
<Input autoCorrect={false} />
<Input autoCorrect={true} />
// String values (web-style, converted on native)
<Input autoCorrect="off" />
<Input autoCorrect="on" />
```
### autoCapitalize
Controls automatic text capitalization. Native values provide more granular control:
```tsx
// Native-style values (recommended - work everywhere)
<Input autoCapitalize="none" /> // No capitalization
<Input autoCapitalize="sentences" /> // Capitalize first letter of sentences
<Input autoCapitalize="words" /> // Capitalize first letter of each word
<Input autoCapitalize="characters" /> // Capitalize all characters
// Web-style values (mapped on native)
<Input autoCapitalize="off" /> // Maps to "none" on native
<Input autoCapitalize="on" /> // Maps to "sentences" on native
```
## Migration from v1
If you're migrating from v1 Input, here are the key changes:
| v1 (React Native style) | v2 (Web style) |
| ------------------------------ | ---------------------------- |
| `secureTextEntry` | `type="password"` |
| `keyboardType="email-address"` | `type="email"` |
| `keyboardType="phone-pad"` | `type="tel"` |
| `keyboardType="numeric"` | `type="number"` |
| `keyboardType="url"` | `type="url"` |
| `returnKeyType="search"` | `enterKeyHint="search"` |
| `editable={false}` | `readOnly` or `disabled` |
| `onChangeText` | `onChange` |
| `multiline` | Use `TextArea` or `rows > 1` |
| `numberOfLines` | `rows` |
The v1 props still work but are deprecated. We recommend updating to the web-standard props for better cross-platform consistency.
## API Reference
### Input Props
Accepts all HTML `<input>` attributes plus Gui style props.
<PropsTable
data={[
{
name: 'size',
required: false,
type: 'SizeTokens',
description: 'Scale the input size consistently.',
},
{
name: 'type',
required: false,
type: '"text" | "password" | "email" | "tel" | "number" | "url" | "search"',
description: 'HTML input type. Automatically maps to native keyboard types.',
},
{
name: 'enterKeyHint',
required: false,
type: '"enter" | "done" | "go" | "next" | "previous" | "search" | "send"',
description: 'Hint for the enter key label. Maps to returnKeyType on native.',
},
{
name: 'placeholderTextColor',
required: false,
type: 'ColorTokens',
description: 'Color of placeholder text. Accepts Gui color tokens.',
},
{
name: 'selectionColor',
required: false,
type: 'ColorTokens',
description: 'Color of text selection. Accepts Gui color tokens.',
},
{
name: 'onSubmitEditing',
required: false,
type: '(e: { nativeEvent: { text: string } }) => void',
description: 'Called when enter/return is pressed.',
},
{
name: 'keyboardAppearance',
required: false,
type: '"default" | "light" | "dark"',
description: 'iOS only. Controls keyboard color scheme.',
},
{
name: 'textContentType',
required: false,
type: 'string',
description: 'iOS only. Hints for autofill. Use autoComplete for web.',
},
]}
/>
### TextArea Props
Accepts all Input props plus:
<PropsTable
data={[
{
name: 'rows',
required: false,
type: 'number',
description: 'Number of visible text lines.',
},
]}
/>