Bestax 表单构建

使用 bestax-bulma 组件和由应用管理的验证机制,构建响应式 React 表单。

allxsmith
2026年10月8日
0 收藏
90 下载

安装与下载

1 ClawHub CLI

从源直接安装技能的最快方式。

npx clawhub@latest install bestax-form

2 手动安装

将技能文件夹复制到以下位置之一

全局模式 ~/.openclaw/skills/
工作区 {'/skills/'}

优先级:工作区 › 全局 › 内置

3 提示词安装

将此提示词复制到 Openclaw 即可自动安装。

请帮我使用 Clawhub 安装 skill-bestax-form。如果尚未安装 Clawhub,请先安装(npm i -g clawhub)。

更倾向于下载?

获取包含原生技能文件的ZIP压缩包。

下载技能 (.zip)

基本信息

名称 Bestax 表单构建
Slug bestax-form
创建者 allxsmith
创建时间 2026-10-08 05:55:28
更新时间 2026-10-08 05:55:28
收藏数 0
使用量 90
浏览量 1

安装指南

  1. ClawHub CLI 从源直接安装技能的最快方式。
    npx clawhub@latest install bestax-form
  2. 手动安装 将技能文件夹复制到以下位置之一
    全局模式
    ~/.openclaw/skills/
    工作区
    /skills/
    优先级:工作区 > 本地 > 内置
  3. 提示词安装 将此提示词复制到 OpenClaw 即可自动安装。
    请帮我使用 Clawhub 安装 bestax-form。如果尚未安装 Clawhub,请先安装(npm i -g clawhub)。
    更倾向于下载?
    获取包含原生技能文件的ZIP压缩包。
    下载技能 (.zip)

什么是

Bestax 表单构建将指导开发者使用 @allxsmith/bestax-bulma 组合表单,涵盖标准输入框和下拉选择框,以及复选框、开关、自动完成、滑块、评分、标签、文件上传和日期/时间控件。常见字段可使用便捷组件,也可以组合 Field、Control 和 *Base 组件来构建分组布局和自定义组合。
此技能强调一项重要限制:bestax-bulma 不包含表单或验证库。表单状态和验证由你的应用负责管理,再通过 color、message 和 messageColor 等输入属性传递字段状态。这些实用模式让 Openclaw Skills 有助于构建易于访问且一致的表单,同时不要求使用特定的状态管理或验证框架。

应用场景

使用 bestax-bulma 输入框、下拉选择框、文本区域、复选框、单选按钮、开关或高级控件构建表单。
在便捷组件与显式的
Field
+
Control
+ *Base 组合方式之间进行选择。
添加帮助文本,并传达验证错误或字段验证成功状态。
创建水平、分组或输入框与按钮附加组合布局。
将受控输入连接到 React 状态,或集成你选择的验证库。
在完成工作前,先在浏览器中检查表单行为和视觉状态。

工作原理

确定所需的表单控件和布局,然后优先复用已提供的 bestax-bulma 组件,而不是自行编写输入控件。
对普通的单控件字段,使用 Input 或 Select 等便捷组件;需要分组控件、附加组件或自定义布局时,使用 Field、Control 和基础组件。
使用 React 状态、reducer 或其他库在应用中保存值和交互状态。bestax-bulma 不提供 useForm hook 或内置验证功能。
在应用中计算验证结果,并通过 color、message 和 messageColor 反映到输入控件上;适用时,错误使用 danger,有效状态使用 success。
确保标签与控件相关联,包括为多控件字段中的各个控件分别设置标签,并为受控输入同时提供 value 和 onChange。
适当时,使用推荐的 Toast 处理提交反馈,并使用 Dialog 处理确认流程。
运行应用或 Storybook,并在浏览器中检查布局、间距以及有效和错误状态;在无头环境中,可将渲染为字符串的冒烟测试作为有限的替代方案。

配置指南

使用项目已有的包管理器和设置约定,在 React 项目中安装 @allxsmith/bestax-bulma 包。导入所需组件,然后将它们连接到应用管理的状态。此技能未指定软件包安装命令,也未规定使用某个验证库。

在 bulma-ui 工作区中启动 Storybook,以检查表单组件

pnpm storybook
对于常见字段,将标签和受控值传递给便捷组件。根据应用计算出的错误提供 color、message 和 messageColor,以添加验证反馈。对于自定义字段布局,可组合 Field + Control + 基础组件。如果采用推荐的提交反馈或确认模式,请在应用根节点挂载 ToastContainer 或 DialogContainer。有关特定组件的属性,请查阅软件包文档和 references/api.md;更完整的表单示例请参阅 references/patterns.md。

数据架构

此技能不定义持久化数据架构、不生成表单数据文件,也不管理提交。表单值、已触碰状态和验证结果由应用负责管理;可以将它们保存在 React 状态、reducer 或开发者选择的库中。
关注事项 组织与处理方式
表单值 由应用管理的受控值(value + onChange),或非受控初始值(defaultValue)。
验证 由应用计算;没有内置验证引擎,也未规定使用某个库。
字段反馈 便捷输入属性:color、message 和 messageColor。将验证状态设置在输入控件上;Field 不会渲染自己的验证消息或颜色状态。
布局 Field 处理 horizontal、grouped 和 hasAddons 等布局模式;Control 包装输入控件,并可提供图标或加载状态。
标签与无障碍性 便捷组件会将标签与生成或提供的 ID 相关联;显式组合和多控件字段可能需要为每个控件有意单独设置标签。
组件分类 Input、Select、TextArea、checkbox/radio 组、Switch、File、Autocomplete、Slider、Numberinput、Rate、Taginput 和日期/时间输入控件;基础变体支持显式组合。

高级特性

Field
布局属性组合水平字段、分组控件以及连接在一起的输入框/按钮附加组件。
Control
添加左/右图标、加载指示器、扩展控件和尺寸设置。
在受支持的组件上应用 Bulma 辅助属性,以设置间距、文本颜色和显示样式。
使用自动完成建议和键盘导航、单滑块或双滑块、数字步进器、精度评分、标签建议以及日期/时间输入控件,构建更丰富的交互。
通过将外部验证的值和错误字符串映射到组件属性来进行集成;此技能不会限定你必须使用某个表单库。
使用 Toast 提供短暂的提交反馈,并使用 Dialog 处理基于 promise 的确认流程;两者也都支持受控组件模式。
在 Storybook 或文档浏览器中验证视觉行为,包括字段对齐和验证状态;在无头 CI 中,使用生产构建和
renderToString
冒烟测试,同时记录浏览器检查仍未完成。
优先使用文档中规定的拼写
Numberinput
Taginput
;
NumberInput
TagInput
是已弃用的别名。


name: bestax-form description: Build forms with @allxsmith/bestax-bulma — Field/Control/Label/Help composition, inputs, selects, checkboxes, radios, switches, and advanced controls (Autocomplete, Slider, Numberinput, Rate, Taginput, File, date/time). There is no form/validation library; this skill shows the components and the validate-it-yourself error pattern. Use when building a form, wiring inputs to state, or showing validation/error state.

Building forms with bestax-bulma

This skill covers the form components in @allxsmith/bestax-bulma and how to compose them.

Important: bestax-bulma ships no form/validation library — there is no integration with formik, react-hook-form, yup, or zod, and no useForm-style hook. You own your form state with plain React (useState / useReducer or any library you choose) and feed validation results back via each input's own color, message, and messageColor props on the convenience inputs (Input, Select, TextArea, …). Always put validation state on the input: Field has no message/messageColor, and although FieldProps types a color, Field discards it — it renders no class, so setting it looks right and does nothing. (FieldLabel/FieldBody do honor color, as the has-text-* helper.) See Validation without a library below.

Use when

Building a form out of bestax inputs, selects, checkboxes, switches, or advanced controls.
Deciding between the convenience components () and explicit Field + Control + *Base composition.
Showing help text and error/success states on fields.

To build a brand-new input component (not just use the existing ones), use the bestax-custom-component skill instead.

Field / Control / Label / Help composition

Bulma forms are a three-tier structure. bestax models it directly:

Field // container + layout (horizontal / grouped / hasAddons)
├── label // rendered from Field's label prop, or when horizontal
└── Control // wraps ONE input; adds icons + loading
├── InputBase / SelectBase / TextAreaBase // the raw styled element
└──
…
// help / validation message

You rarely write all of this by hand. The convenience components (Input, Select, TextArea, …) auto-wrap themselves in Field + Control when they aren't already inside one, using context (useInsideField / useInsideControl) to detect their surroundings.

// Convenience: one line, auto-wrapped in Field + Control.

// Explicit composition: full control over layout.

Layout via Field

horizontal — label and control side by side (wraps children in Field.Body; use Field.Label / Field.Body directly for multi-control rows).
grouped — true | 'centered' | 'right' | 'multiline', controls in a row.
hasAddons — true | 'centered' | 'right', attached controls (input + button).

Go

Component inventory

All import from @allxsmith/bestax-bulma. Convenience components auto-wrap Field+Control; *Base components are the raw styled elements for explicit composition.

Component What it is

Field, Field.Label, Field.Body Field container + horizontal label/body parts.
Control Wraps one input; left/right icons, isLoading, isExpanded, size.
Input / InputBase Text input (convenience / raw).
Select / SelectBase Dropdown select.
TextArea / TextAreaBase Multiline text.
Checkbox / Checkboxes Single checkbox / managed group (array value).
Radio / Radios Single radio / managed single-select group.
Switch Toggle switch (isRounded, isThin, isOutlined, RTL).
File File upload input with label/message.
Autocomplete Input with filtered dropdown suggestions + keyboard nav.
Slider Range slider; single/dual thumbs, steps, tooltips, vertical.
Numberinput Numeric input with increment/decrement, min/max, step, stepper.
Rate Star rating; max, precision (half/quarter), custom icons, disabled.
Taginput Tag/chip input; suggestions, confirm keys, closable tags.
DateInput / TimeInput / DateTimeInput (+ *Base) Date / time / datetime pickers.

(NumberInput and TagInput also exist as deprecated aliases of Numberinput/Taginput — same components; prefer the lowercase-second-word spellings.)

Common props

Across the convenience inputs (Input, Select, TextArea, and similar):

Prop Type Purpose

color 'primary' | 'link' | 'info' | 'success' | 'warning' | 'danger' Visual state — use 'danger' for errors, 'success' for valid.
size 'small' | 'medium' | 'large' Input size.
value / onChange controlled value + handler Standard React controlled inputs.
defaultValue uncontrolled initial value When not controlling state.
disabled, readOnly boolean Native states (readOnly on *Base).
label ReactNode Field label (convenience components; auto-associated via htmlFor).
message ReactNode Help / validation text rendered as
.
messageColor a Bulma color Colors the help text ('danger' for errors).
iconLeftName / iconRightName string Icon shortcuts; pair with hasIconsLeft/Right.
isLoading boolean Loading indicator on the Control.

Plus the full Bulma helper props (m, p, textColor, display, …) on every component via useBulmaClasses.

Full-width is isFullwidth on every component that supports it (Button, LinkButton, Select, File, Table, Tabs, Sidebar) — always write isFullwidth. The deprecated spellings compile only where they historically existed: isFullWidth everywhere except Sidebar, fullwidth on Tabs only, fullWidth on Sidebar only.

The label prop on the single-control convenience inputs (Input, Select, TextArea, File, Numberinput, Slider, DateInput, TimeInput, DateTimeInput, Autocomplete, Taginput) wires htmlFor/id automatically — your id is used when provided, a generated one otherwise, and an explicit labelProps={{ htmlFor }} wins. The wiring only happens when the component renders its own Field (nested inside one, the label prop is dropped); the date/time pickers skip it in inline mode and Taginput skips it at maxTags (no visible input to label). The group inputs (Checkboxes, Radios, Rate) associate their label too, but group-style: the wrapper gets role="group"/"radiogroup" and aria-labelledby pointing at the label. Composing Field + bases yourself also associates: Field's own label wires to a single composed InputBase/SelectBase/ TextAreaBase (skipped for grouped/hasAddons). Pass labelProps={{ htmlFor }} plus a matching id only when you want a stable id, or labelProps={{ htmlFor: undefined }} to opt out — e.g. when the labeled Field wraps something that is not one of those bases.

Convenience vs composed

Convenience () — for typical, single-control fields. Fewer lines, auto-wrapping, built-in message/messageColor. Default to this.
Composed (Field + Control + InputBase) — when you need grouped controls, addons, multiple controls per field, or custom layout. The convenience components detect they're already inside a Field/Control and won't double-wrap, so you can mix the two.

Validation without a library

There is no built-in validation. The pattern is: own your state, compute errors yourself, and reflect them with color + message + messageColor.

import { useState } from 'react';
import { Input, Button } from '@allxsmith/bestax-bulma';

function SignupForm() {
const [email, setEmail] = useState('');
const [touched, setTouched] = useState(false);

const valid = /^[^@\s]+@[^@\s]+.[^@\s]+$/.test(email);
const error =
touched && !valid ? 'Please enter a valid email address.' : undefined;

return (
{
e.preventDefault();
setTouched(true);

if (valid) {

// submit…
}
}}

setEmail(e.target.value)}
onBlur={() => setTouched(true)}
color={error ? 'danger' : undefined}
message={error}
messageColor={error ? 'danger' : undefined}
iconLeftName="envelope"
/>

Sign up

);
}

Rules of thumb:

Set color="danger" on the input and messageColor="danger" on the help text so both the control and the message read as an error. Use 'success' to signal a valid field.
Want a different validation library? Wire it up yourself — pass its value/onChange/error string into these props. bestax does not prescribe one.
For grouped controls, render the
via the message prop of the convenience component, or add it manually inside the Field when composing.

See references/api.md for per-component props and references/patterns.md for a full multi-field form plus the advanced inputs.

Reuse the shipped components

bestax ships the whole form surface — Input, Select, TextArea, Checkbox(es), Radio(s), Switch, File, Autocomplete, Slider, Numberinput, Rate, Taginput, and the date/time inputs (see the inventory above). Compose these; don't hand-roll raw markup or reinvent a control. If you think a control is missing, check bulma-ui/src/index.ts and docs/docs/api/form/ first — it's probably already there under a different name.

What happens after submit

A form is not finished at the last field. The two components that carry the result are easy to miss because Bulma has something that looks close:

Confirmation — Toast, not Notification/Message. Mount once at the app root, then call toast.success('Demo booked') from the submit handler (.danger for a failed submit). It self-dismisses.
"Are you sure?" — Dialog, not Modal. Mount at the root, then if (await dialog.confirm({ title: 'Delete this key?', message: '…', type: 'danger' })) …. It resolves to a boolean, so a destructive action stays one if rather than a state machine. Modal is an empty shell — with it you rebuild the title, message and button row by hand.

Both also work as plain controlled components (, ) when the state should live in your component.

Visually inspect it in a browser

Forms have layout, spacing, and stateful behavior that types and unit tests don't cover. Before calling a form done, render it and look at it: run pnpm storybook (in bulma-ui) or the docs dev server, open the form, and check field alignment/spacing, the help-text/error states, and the validation flow (submit empty → fields turn danger with messages; fix → errors clear). If claude-in-chrome or Playwright is available, drive the browser and screenshot the valid and error states; otherwise eyeball it yourself. No browser at all (headless CI)? Fall back to a production build plus a Node renderToString smoke render, grep the emitted HTML for the expected classes/states, and say plainly that the visual pass is still owed.

Checklist

Built from the shipped form components (no hand-rolled inputs / reinvented controls).
Every label is programmatically associated — the convenience label prop, the group inputs, and Field + single-base composition all do this automatically; pass labelProps={{ htmlFor }} plus a matching id only for a stable id, and label a multi-control Field's controls individually (aria-label, aria-labelledby, or a matching each control's id).
Controlled inputs have both value and onChange (or use defaultValue uncontrolled).
Error state shows via color="danger" + message + messageColor="danger".
Grouped/addon layouts use explicit Field + Control composition.
No assumption of a built-in validation/form library — state is owned by the app.
Submit feedback is a Toast and any "are you sure?" is a Dialog — not a hand-placed Notification or a Modal you filled in yourself.
Rendered and visually inspected in a browser — layout and the error/validation states look right, not just green tests. No browser available? The renderToString fallback above counts only if you grepped the emitted classes/states and said the visual pass is owed.
Bestax 自定义组件
暂无数据