Bỏ qua tới nội dung
Component / 054 / NEXOFRAME

Composer

Mẫu chuẩn

Ô soạn trong một shell compact: cao dần theo chữ tới trần token, preset theo bề mặt, slot host cho context và footer icons. Host giữ value / onSubmit / lockedReason. Nháp AI nằm ngoài Composer.

Composite tầng 2Shell + auto-growPresets: default · omnichat · crew · nexi · widgetFocus ring trên shell

Playground

Chọn preset. Omnichat hiện icon footer giả (host slot). Nexi/widget = shell compact + send icon. Ctrl/⌘+Enter để gửi · Enter xuống dòng.

LIVE PREVIEW
FB · Đơn 1042

Chưa gửi tin nào.

import { Composer } from "@nexobox/ui";

<Composer
  preset="omnichat"
  value={value}
  onValueChange={setValue}
  onSubmit={(next) => send(next)}
  label="Câu trả lời"
  submitLabel="Gửi cho khách"
  placeholder="…"
  context={<ContextChips />}
  footerActions={<ActionIcons />}
/>

Bài toán

Người vận hành gõ trả lời trên nhiều bề mặt. Ô soạn phải gọn khi nghỉ, lớn theo chữ tới trần token, có slot icon Omnichat và báo khi bị khoá. Textarea + Button riêng không đủ.

Khi nào sử dụng

Nên dùng

Gửi một tin trong hội thoại. Khi người dùng có thể bị chặn gửi vì một lý do cần giải thích.

Khi nào không dùng

Tránh dùng

Không dùng choDùng thay
Trường văn bản dài trong biểu mẫuTextarea trong Field
Nháp AI / streamingMessageBubble / NexiIsland phía trên Composer
Upload file thậtHost; Composer chỉ nhận slot attachments

Dựng từ

Primitive tầng 1Vai trong composite
LabelNhãn của ô (sr-only mặc định).
textarea nội bộAutosize trong shell; tắt resize tay.
ButtonGửi chữ (footer) hoặc icon ArrowUp (trailing).

Anatomy

#PhầnGhi chú
1Lý do khoáCaption ngoài shell khi có lockedReason.
2ShellBorder control, surface raised, field shadow; focus ring một lần.
3Context / AttachmentsSlot host, tùy chọn.
4Input rowleading · textarea · trailing · send icon (preset nexi/widget).
5FooterfooterActions + send chữ khi placement footer.

Presets

PresetSendEnter
default / omnichat / crewFooter chữCtrl/⌘+Enter gửi
nexi / widgetTrailing iconEnter gửi

States

Trạng tháiBiểu hiện
CompactMột dòng ≈ field-height
GrownCao theo nội dung
OverflowingĐạt max-height → cuộn trong ô
FooterHàng footer hiện (omnichat luôn)
Focused shellRing trên shell, không double
Rỗng / Có chữSend disabled / enabled
Đang gửisubmitting: loading + readOnly
Bị khoálockedReason / disabled

Bàn phím & trợ năng

default / omnichat / crew: Enter xuống dòng; Ctrl/⌘+Enter gửi.
nexi / widget: Enter gửi; Shift+Enter xuống dòng.
Tab: leading → textarea → trailing/footer → send.
submitLabel là aria-label khi send là icon.

Seam — host sở hữu gì

Composite không gửi tin, không xoá ô, không upload, không giữ nháp AI.

Host sở hữuCấp qua
Giá trị đang gõvalue / onValueChange
Gọi dịch vụ, submitting, clearonSubmit
Icon Omnichat / context / attachmentsfooterActions, context, attachments
Lý do khoálockedReason

API & triển khai

PropMặc địnhQuy ước
value—Bắt buộc.
onValueChange—Bắt buộc.
onSubmit—Bắt buộc.
label—Bắt buộc.
labelHiddentrue—
submitLabel—Chữ Button hoặc aria-label icon.
placeholderundefined—
submittingfalse—
lockedReasonundefinedCó thì khoá.
disabledfalseKhoá không cần lý do.
preset"default"default | omnichat | crew | nexi | widget
submitOnEntertheo presetOverride Enter.
sendPlacementtheo presetfooter | trailing
maxHeightvar(--nf-component-composer-max-height)CSS length.
contextundefinedZone context.
attachmentsundefinedZone attachments (slot only).
leadingundefined—
trailingundefined—
footerActionsundefinedHost icon bar.
actionsundefinedDeprecated — alias footerActions.

Design tokens

--nf-component-composer-max-height (DS-019), --nf-component-field-height, --nf-component-field-shadow, --nf-component-focus-*, --nf-component-transition-*, --nf-semantic-surface-raised, --nf-semantic-border-control. Không token shell mới trong phase này.

Do / Don't

Nên dùng

Host xoá ô sau gửi thành công. Nháp AI ngoài Composer. Omnichat icons qua footerActions. Một focus ring trên shell.

Tránh dùng

Khoá không nói lý do. Hardcode task CRM trong kit. Upload trong Composer. Đổ nháp AI vào ô soạn. Ring kép.