npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

xhub-keyboard

v0.0.23

Published

A custom react keyboard

Downloads

133

Readme

XHubKeyboard

Thư viện React component cho bàn phím ảo với giao diện đẹp và dễ tùy chỉnh.

Cài đặt

npm install xhub-keyboard
# hoặc
yarn add xhub-keyboard

Các Component Chính

1. Input Component

Component input field với khả năng tùy chỉnh cao và hỗ trợ nhiều kiểu hiển thị.

import { Input, THEME, DisplayType } from "xhub-keyboard";

function InputExample() {
  const [value, setValue] = useState("");

  return (
    <Input
      value={value}
      placeholder="Nhập văn bản..."
      theme={THEME.DARK}
      displayType={DisplayType.Text}
      leftElement={<span>🔍</span>}
      rightElement={<span>✓</span>}
      onFocus={() => console.log("Input focused")}
      onBlur={() => console.log("Input blurred")}
    />
  );
}

Props của Input

| Prop | Type | Default | Mô tả | | ------------------- | --------------------------------- | ------------------ | ------------------------------- | | value | string | - | Giá trị hiện tại | | placeholder | string | - | Placeholder text | | theme | THEME | THEME.LIGHT | Theme của input | | displayType | DisplayType | DisplayType.Text | Kiểu hiển thị giá trị | | leftElement | ReactNode | - | Element bên trái input | | rightElement | ReactNode | - | Element bên phải input | | onFocus | () => void | - | Callback khi focus | | onBlur | () => void | - | Callback khi blur | | autoFocus | boolean | false | Tự động focus | | alwaysFocus | boolean | false | Luôn giữ focus | | isUseFormatNumber | boolean | true | Sử dụng format số | | replaceElement | ReactNode | "●" | Element thay thế cho Replace | | renderValue | (value: ReactNode) => ReactNode | - | Hàm render giá trị tùy chỉnh | | elementsAcceptIds | string[] | - | IDs của elements được chấp nhận | | styles | InputStyleProps | - | Custom styles | | classNames | InputClassNames | - | Custom class names |

2. Keyboard Component

Component bàn phím ảo với nhiều layout khác nhau và hỗ trợ keyboard events.

import { Keyboard, THEME, KeyboardType, LayoutType } from "xhub-keyboard";

function KeyboardExample() {
  const [value, setValue] = useState("");

  return (
    <Keyboard
      value={value}
      onChange={setValue}
      theme={THEME.LIGHT}
      keyboardType={KeyboardType.Number}
      layoutType={LayoutType.Decimal}
      alwaysOpen={true}
      onOpen={(height) => console.log("Keyboard opened, height:", height)}
      onClose={() => console.log("Keyboard closed")}
      toolbar={<div>Toolbar tùy chỉnh</div>}
    />
  );
}

Props của Keyboard

| Prop | Type | Default | Mô tả | | ------------------------ | --------------------------- | --------------------- | ------------------------------ | | value | string | "" | Giá trị hiện tại | | onChange | (value: string) => void | - | Callback khi giá trị thay đổi | | theme | THEME | THEME.LIGHT | Theme của keyboard | | keyboardType | KeyboardType | KeyboardType.Number | Loại keyboard | | layoutType | LayoutType | LayoutType.Decimal | Layout của keyboard | | alwaysOpen | boolean | false | Luôn hiển thị keyboard | | openInit | boolean | false | Hiển thị keyboard khi khởi tạo | | toolbar | ReactNode | - | Toolbar tùy chỉnh | | onOpen | (height?: number) => void | - | Callback khi mở keyboard | | onClose | () => void | - | Callback khi đóng keyboard | | validateKeyValue | (value: string) => string | - | Validate giá trị nhập | | outFocusOnClickToolbar | boolean | true | Mất focus khi click toolbar | | id | string | - | ID của keyboard container | | keyboardId | string | - | ID của keyboard section | | toolbarId | string | - | ID của toolbar | | children | ReactNode | - | Children elements | | viewFullHeight | boolean | false | Hiển thị full height | | styles | KeyboardStyleProps | - | Custom styles | | classNames | KeyboardClassNamesProps | - | Custom class names |

3. Label Component

Component hiển thị nhãn với khả năng trigger keyboard và hỗ trợ browser input.

import { Label } from "xhub-keyboard";

function LabelExample() {
  return (
    <Label htmlFor="my-keyboard" className="custom-label">
      Nhãn tùy chỉnh
    </Label>
  );
}

Props của Label

| Prop | Type | Default | Mô tả | | ----------------- | --------------------------------------------- | ------- | ---------------------------- | | htmlFor | string | - | ID của element được liên kết | | className | string | - | Custom class name | | children | ReactNode | - | Nội dung của label | | inputProps | React.InputHTMLAttributes<HTMLInputElement> | - | Props cho input element | | useBrowserInput | boolean | false | Sử dụng browser input |

Enums và Types

THEME

enum THEME {
  LIGHT = "tek-keyboard-light",
  DARK = "tek-keyboard-dark",
}

DisplayType

enum DisplayType {
  Text = "text", // Hiển thị dạng text
  Number = "number", // Hiển thị dạng số
  Replace = "replace", // Hiển thị dạng thay thế
}

KeyboardType

enum KeyboardType {
  Text = "text", // Bàn phím text
  Number = "number", // Bàn phím số
}

LayoutType

enum LayoutType {
  Text = "text", // Layout text
  Number = "number", // Layout số
  Decimal = "decimal", // Layout số thập phân
}

Utility Functions

formatValues

Format giá trị số với dấu phẩy ngăn cách hàng nghìn.

import { formatValues } from "xhub-keyboard";

const result = formatValues("1234567.89");
// Kết quả: { value: "1234567.89", displayValue: "1,234,567.89" }

getStandardValues

Chuyển đổi giá trị thành định dạng chuẩn dựa trên DisplayType.

import { getStandardValues, DisplayType } from "xhub-keyboard";

// Text display
const textResult = getStandardValues("Hello", DisplayType.Text);
// Kết quả: { displayValue: ["H", "e", "l", "l", "o"], value: "Hello" }

// Replace display
const replaceResult = getStandardValues("1234", DisplayType.Replace, "•");
// Kết quả: { displayValue: ["•", "•", "•", "•"], value: "1234" }

Styling và Customization

CSS Classes

Component sử dụng CSS classes có thể tùy chỉnh:

  • .tek-keyboard-light - Theme sáng
  • .tek-keyboard-dark - Theme tối
  • .input-container - Container của input
  • .keyboard-container - Container của keyboard
  • .keyboard-section - Section chứa keyboard
  • .board-of-keys-container - Container của các phím
  • .keyboard-trigger - Trigger để mở keyboard
  • .label-container - Container của label

Custom Styles

Bạn có thể truyền custom styles thông qua props:

<Input
  styles={{
    container: { backgroundColor: "#f0f0f0" },
    input: { border: "2px solid #007bff" },
    text: { fontSize: "16px" },
    placeholder: { color: "#666" },
  }}
  classNames={{
    container: "custom-input-container",
    input: "custom-input",
  }}
/>
<Keyboard
  styles={{
    container: { backgroundColor: "#ffffff" },
    keyboardContainer: { border: "1px solid #ddd" },
    keyboards: { gap: "8px" },
    key: { backgroundColor: "#e9ecef" },
    toolbar: { padding: "12px" },
  }}
  classNames={{
    container: "custom-keyboard",
    theKey: {
      key: "custom-key",
      label: "custom-key-label",
    },
  }}
/>

Ví dụ Sử Dụng

Ví dụ 1: Input với format số

import { Input, THEME, DisplayType } from "xhub-keyboard";

function NumberInput() {
  const [value, setValue] = useState("");

  return (
    <Input
      value={value}
      placeholder="Nhập số..."
      theme={THEME.LIGHT}
      displayType={DisplayType.Number}
      isUseFormatNumber={true}
      leftElement={<span>💰</span>}
    />
  );
}

Ví dụ 2: Input với Replace display

import { Input, THEME, DisplayType } from "xhub-keyboard";

function PasswordInput() {
  const [value, setValue] = useState("");

  return (
    <Input
      value={value}
      placeholder="Nhập mật khẩu..."
      theme={THEME.DARK}
      displayType={DisplayType.Replace}
      replaceElement="•"
      rightElement={<span>👁️</span>}
    />
  );
}

Ví dụ 3: Keyboard với Label

import { Keyboard, Label, THEME, KeyboardType, LayoutType } from "xhub-keyboard";

function KeyboardWithLabel() {
  const [value, setValue] = useState("");

  return (
    <div>
      <Label htmlFor="amount-keyboard">Số tiền:</Label>
      <Keyboard
        id="amount-keyboard"
        value={value}
        onChange={setValue}
        theme={THEME.LIGHT}
        keyboardType={KeyboardType.Number}
        layoutType={LayoutType.Decimal}
        toolbar={<div>Nhập số tiền</div>}
      />
    </div>
  );
}

Ví dụ 4: Keyboard luôn mở với custom styles

import { Keyboard, THEME } from "xhub-keyboard";

function AlwaysOpenKeyboard() {
  const [value, setValue] = useState("");

  return (
    <Keyboard
      value={value}
      onChange={setValue}
      theme={THEME.LIGHT}
      alwaysOpen={true}
      viewFullHeight={true}
      styles={{
        container: { backgroundColor: "#f8f9fa" },
        keyboardContainer: { backgroundColor: "#ffffff" },
        key: {
          backgroundColor: "#007bff",
          color: "#ffffff",
          borderRadius: "8px",
        },
      }}
      toolbar={<div>Bàn phím luôn mở</div>}
    />
  );
}

Ví dụ 5: Input với custom render

import { Input, THEME, DisplayType } from "xhub-keyboard";

function CustomRenderInput() {
  const [value, setValue] = useState("");

  const renderValue = (char: ReactNode) => (
    <span
      style={{
        color: char === "A" ? "red" : "blue",
        fontWeight: "bold",
      }}
    >
      {char}
    </span>
  );

  return (
    <Input
      value={value}
      placeholder="Nhập văn bản..."
      theme={THEME.LIGHT}
      displayType={DisplayType.Text}
      renderValue={renderValue}
    />
  );
}

Keyboard Events

Keyboard component hỗ trợ các phím vật lý:

  • Các phím số (0-9)
  • Phím dấu chấm (.)
  • Phím Backspace/Delete
  • Các phím chữ cái (a-z, A-Z)

Browser Support

  • Chrome 60+
  • Firefox 55+
  • Safari 12+
  • Edge 79+

Dependencies

  • React 18.0.0+
  • React DOM 18.0.0+
  • clsx 2.1.1+

License

ISC License

xhub-keyboard