Skip to content

Input

Trường nhập liệu văn bản với nhãn và trạng thái xác thực.

Cài đặt

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
# Nếu bạn đã cài galaxy-design global
galaxy-ui add input

Dependencies

Component này tự động cài đặt các dependencies sau:

Không cần cài đặt thủ công!

Sử dụng

Ví dụ cơ bản

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

export default function App() {
  return (
    <Input
      type="email"
      placeholder="Nhập email của bạn"
      className="w-full max-w-sm"
    />
  )
}
vue
<script setup lang="ts">
import { Input } from '@/components/ui/input'
</script>

<template>
  <Input
    type="email"
    placeholder="Nhập email của bạn"
    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="Nhập email của bạn"
      class="w-full max-w-sm"
    />
  `
})
export class AppComponent {}
tsx
import { Input } from '@/components/ui/input'

export default function App() {
  return (
    <Input
      placeholder="Nhập email của bạn"
      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: 'Nhập email của bạn',
      keyboardType: TextInputType.emailAddress,
    );
  }
}

Với 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="Nhập email của bạn"
        ariaInvalid={true}
      />
      <p className="text-sm text-red-500">Email là bắt buộc</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="Nhập email của bạn"
      aria-invalid="true"
    />
    <p class="text-sm text-red-500">Email là bắt buộc</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="Nhập email của bạn"
        [ariaInvalid]="true"
      />
      <p class="text-sm text-red-500">Email là bắt buộc</p>
    </div>
  `
})
export class AppComponent {}
tsx
import { Input } from '@/components/ui/input'

export default function App() {
  return (
    <Input
      label="Email"
      placeholder="Nhập email của bạn"
      error="Email là bắt buộc"
      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: 'Nhập email của bạn',
      errorText: 'Email là bắt buộc',
      keyboardType: TextInputType.emailAddress,
    );
  }
}

API Reference

Props

PropKiểuMặc địnhMô tảFrameworks
typestring"text"Loại input (text, password, email, number, v.v.)Web only (React, Vue, Angular)
value / modelValuestring | number-Giá trị được kiểm soátReact/Angular: value, Vue: modelValue
defaultValuestring | number-Giá trị khởi tạo không kiểm soátReact only
placeholderstring-Văn bản placeholderTất cả
disabledbooleanfalseVô hiệu hóa inputTất cả
readOnly / readonlybooleanfalseLàm cho input chỉ đọcWeb only (React: readOnly, Angular: readonly)
maxLength / maxlengthnumber-Độ dài tối đa của inputWeb only (React: maxLength, Angular: maxlength)
autoComplete / autocompletestring-Gợi ý autocompleteWeb only
ariaInvalidboolean | string-Trạng thái ARIA invalidWeb only (React, Angular)
className / classstring""Tên class CSSReact: className, Vue/Angular: class
onChange / update:modelValue / onChangeTextFunction-Handler khi thay đổiReact: onChange, Vue: update:modelValue, Mobile: onChangeText
editablebooleantrueInput có chỉnh sửa được hay khôngReact Native only
label / labelTextstring-Văn bản nhãnMobile only (React Native: label, Flutter: labelText)
error / errorTextstring-Văn bản lỗiMobile only (React Native: error, Flutter: errorText)
enabledbooleantrueInput có được bật hay khôngFlutter only
obscureTextbooleanfalseẨn văn bản input (cho mật khẩu)Flutter only
keyboardTypestring / TextInputType-Loại bàn phímMobile only (React Native: string, Flutter: TextInputType)
maxLinesnumber1Số dòng tối đaFlutter only
controllerTextEditingController-Controller cho text fieldFlutter only
onSubmitted / onSubmit(value: string) => void-Handler khi submitMobile only
containerClassNamestring-Tên class wrapperReact Native only
labelClassNamestring-Tên class nhãnReact Native only
inputClassNamestring-Tên class inputReact Native only
errorClassNamestring-Tên class lỗiReact Native only
onBlur(event) => void-Handler khi mất focusReact Native only
onFocus(event) => void-Handler khi nhận focusReact Native only

Khả năng truy cập

  • Điều hướng bàn phím: Điều hướng bàn phím chuẩn cho input
  • Đọc màn hình: Sử dụng thẻ <input> ngữ nghĩa với nhãn
  • Quản lý focus: Focus được hiển thị với viền ring
  • Tuân thủ WCAG: Tuân thủ WCAG 2.1 cấp độ AA

Tác giả

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

Giấy phép

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

Phát hành theo Giấy phép MIT.