Skip to content

Input

A text input field with label and validation states.

Installation

bash
npx @galaxy-stack/nebula-cli@latest add input
bash
pnpm dlx @galaxy-stack/nebula-cli@latest add input
bash
yarn dlx @galaxy-stack/nebula-cli@latest add input
bash
bunx @galaxy-stack/nebula-cli@latest add input
bash
# If you have installed galaxy-design globally
galaxy-design add input

Dependencies

This component automatically installs the following dependencies:

No manual installation needed!

Usage

Basic Example

tsx
import { Input } from "@/components/ui/input"

export default function App() {
  return (
    <Input
      type="email"
      placeholder="Enter your email"
      className="w-full max-w-sm"
    />
  )
}
vue
<script setup lang="ts">
import { Input } from '@/components/ui/input'
</script>

<template>
  <Input
    type="email"
    placeholder="Enter your email"
    class="w-full max-w-sm"
  />
</template>
ts
import { Component } from '@angular/core';
import { InputComponent } from '@/components/ui/input';

@Component({
  selector: 'app-root',
  standalone: true,
  imports: [InputComponent],
  template: `
    <ui-input
      type="email"
      placeholder="Enter your email"
      class="w-full max-w-sm"
    />
  `
})
export class AppComponent {}
tsx
import { Input } from '@/components/ui/input'

export default function App() {
  return (
    <Input
      placeholder="Enter your email"
      keyboardType="email-address"
      className="w-full"
    />
  )
}
dart
import 'package:flutter/material.dart';
import 'package:your_app/components/ui/input.dart';

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return GalaxyInput(
      hintText: 'Enter your email',
      keyboardType: TextInputType.emailAddress,
    );
  }
}

With Form

tsx
import { Input } from "@/components/ui/input"
import { Label } from "@/components/ui/label"

export default function App() {
  return (
    <div className="space-y-2">
      <Label htmlFor="email">Email</Label>
      <Input
        id="email"
        type="email"
        placeholder="Enter your email"
        ariaInvalid={true}
      />
      <p className="text-sm text-red-500">Email is required</p>
    </div>
  )
}
vue
<script setup lang="ts">
import { Input } from '@/components/ui/input'
import { Label } from '@/components/ui/label'
</script>

<template>
  <div class="space-y-2">
    <Label for="email">Email</Label>
    <Input
      id="email"
      type="email"
      placeholder="Enter your email"
      aria-invalid="true"
    />
    <p class="text-sm text-red-500">Email is required</p>
  </div>
</template>
ts
import { Component } from '@angular/core';
import { InputComponent } from '@/components/ui/input';
import { LabelComponent } from '@/components/ui/label';

@Component({
  selector: 'app-root',
  standalone: true,
  imports: [InputComponent, LabelComponent],
  template: `
    <div class="space-y-2">
      <ui-label for="email">Email</ui-label>
      <ui-input
        id="email"
        type="email"
        placeholder="Enter your email"
        [ariaInvalid]="true"
      />
      <p class="text-sm text-red-500">Email is required</p>
    </div>
  `
})
export class AppComponent {}
tsx
import { Input } from '@/components/ui/input'

export default function App() {
  return (
    <Input
      label="Email"
      placeholder="Enter your email"
      error="Email is required"
      keyboardType="email-address"
    />
  )
}
dart
import 'package:flutter/material.dart';
import 'package:your_app/components/ui/input.dart';

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return GalaxyInput(
      labelText: 'Email',
      hintText: 'Enter your email',
      errorText: 'Email is required',
      keyboardType: TextInputType.emailAddress,
    );
  }
}

API Reference

Props

PropTypeDefaultDescriptionFrameworks
typestring"text"Input type (text, password, email, number, etc.)Web only (React, Vue, Angular)
value / modelValuestring | number-Controlled valueReact/Angular: value, Vue: modelValue
defaultValuestring | number-Uncontrolled initial valueReact only
placeholderstring-Placeholder textAll
disabledbooleanfalseDisables the inputAll
readOnly / readonlybooleanfalseMakes the input read-onlyWeb only (React: readOnly, Angular: readonly)
maxLength / maxlengthnumber-Maximum input lengthWeb only (React: maxLength, Angular: maxlength)
autoComplete / autocompletestring-Autocomplete hintWeb only
ariaInvalidboolean | string-ARIA invalid stateWeb only (React, Angular)
className / classstring""CSS class namesReact: className, Vue/Angular: class
onChange / update:modelValue / onChangeTextFunction-Change handlerReact: onChange, Vue: update:modelValue, Mobile: onChangeText
editablebooleantrueWhether the input is editableReact Native only
label / labelTextstring-Label textMobile only (React Native: label, Flutter: labelText)
error / errorTextstring-Error textMobile only (React Native: error, Flutter: errorText)
enabledbooleantrueWhether the input is enabledFlutter only
obscureTextbooleanfalseObscures the input text (for passwords)Flutter only
keyboardTypestring / TextInputType-Keyboard typeMobile only (React Native: string, Flutter: TextInputType)
maxLinesnumber1Max linesFlutter only
controllerTextEditingController-Controller for the text fieldFlutter only
onSubmitted / onSubmit(value: string) => void-Submit handlerMobile only
containerClassNamestring-Wrapper class nameReact Native only
labelClassNamestring-Label class nameReact Native only
inputClassNamestring-Input class nameReact Native only
errorClassNamestring-Error class nameReact Native only
onBlur(event) => void-Blur handlerReact Native only
onFocus(event) => void-Focus handlerReact Native only

Accessibility

  • Keyboard Navigation: Standard input keyboard navigation
  • Screen Reader: Uses semantic <input> element with labels
  • Focus Management: Focus visible with ring styles
  • WCAG Compliance: WCAG 2.1 Level AA compliant

Author

Bùi Trọng Hiếu (kevinbui)

License

MIT © 2025 Bùi Trọng Hiếu (kevinbui)

Released under the MIT License.