news 2026/9/10 15:54:08

Filament Radio 单选框组件完全指南:选项、描述、禁用与布尔模式的源码级解析

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
Filament Radio 单选框组件完全指南:选项、描述、禁用与布尔模式的源码级解析

Filament Radio 单选框组件完全指南:选项、描述、禁用与布尔模式的源码级解析

【免费下载链接】filamentA powerful open-source UI framework for Laravel • Build and ship apps & admin panels fast with Livewire项目地址: https://gitcode.com/GitHub_Trending/fi/filament

Filament 表单包(packages/forms)中的Radio组件用于渲染一组互斥的单选框(radio button group),供用户从预定义选项中选取唯一值。本文以官方文档 07-radio.md 为主线,结合 Radio.php 及其底层 Trait 与测试用例,系统讲解选项定义、选项描述、内联排列、按选项禁用、布尔快捷模式等全部能力,并深入其渲染与状态转换实现,帮助你在 Laravel + Livewire 的 Filament 表单中熟练驾驭该组件。

组件基础:定义选项并绑定状态

Radio组件通过make()指定状态字段名,再以options()方法传入一个「值 => 标签」的关联数组:

use Filament\Forms\Components\Radio; Radio::make('status') ->options([ 'draft' => 'Draft', 'scheduled' => 'Scheduled', 'published' => 'Published', ])

options()不仅支持静态数组,也支持闭包动态计算,并可在闭包中注入表单字段相关的各种工具(Utility Injection,如当前$record$state$get$livewire等)。

从源码看,options()定义于 Concerns/HasOptions.php,其底层签名接受array | Arrayable | string | Closure | null五种形态,并有两个值得注意的细节:

  • 枚举类支持:若传入的字符串是 PHP 枚举类名,options()会自动调用enum();而在getOptions()中(HasOptions.php),如果枚举实现了Filament\Support\Contracts\HasLabel接口,会用getLabel()作为标签,否则以枚举name作为标签。
  • 标签支持嵌套数组options的类型注解为array<string | array<string>>,即每个选项的标签也可以是数组,从而支持分组渲染结构。

Radio在渲染时会为容器添加role="radiogroup"aria-labelledby,保证无障碍语义(见 Radio.php 中的toEmbeddedHtml())。

为选项添加描述文字

当选项较多或含义需要补充说明时,可使用descriptions()为每个选项追加一段辅助描述文字:

use Filament\Forms\Components\Radio; Radio::make('status') ->options([ 'draft' => 'Draft', 'scheduled' => 'Scheduled', 'published' => 'Published', ]) ->descriptions([ 'draft' => 'Is not visible.', 'scheduled' => 'Will be visible.', 'published' => 'Is visible.', ])

务必保证descriptions()数组的keyoptions()数组的key一一对应,描述才会正确匹配到对应选项。

descriptions()同样支持闭包动态计算。其实现位于 Concerns/HasDescriptions.php:

  • 描述数组的类型为array<string | Htmlable> | Arrayable | Closure,描述值可以是纯文本或Htmlable对象;
  • 结果会被缓存(cachedDescriptions),同一生命周期内多次getDescriptions()不会重复求值;
  • 当未显式提供描述、但绑定了枚举且枚举实现了Filament\Support\Contracts\HasDescription接口时,getDescriptions()会自动从枚举的getDescription()生成描述,实现「枚举即描述源」的约定。

测试 RadioTest.php 验证了getDescription('low')hasDescription('missing')等检索行为。

内联排列选项

默认情况下各选项纵向堆叠显示。调用inline()可将选项横向排列成一行:

use Filament\Forms\Components\Radio; Radio::make('feedback') ->label('Like this post?') ->boolean() ->inline()

也可以传入布尔值或闭包,动态控制是否内联:

Radio::make('feedback') ->label('Like this post?') ->boolean() ->inline(FeatureFlag::active())

从源码看(Radio.php),inline()的完整签名为inline(bool | Closure $condition = true),内部保存到$isInline属性,isInline()会通过evaluate()求值闭包。渲染时:

  • 非内联模式下,容器会应用网格布局(grid($this->getColumns(), $gridDirection)),支持通过columns()控制每行选项数量;
  • 内联模式下为容器追加fi-inlineCSS 类(见 Radio.php)。

测试 RadioTest.php 验证了默认isInline()false、调用inline()后为true;L212-L225 进一步验证闭包内联与inline(false)撤销内联均可用。

禁用特定选项与校验联动

使用disableOptionWhen()禁用指定选项

disableOptionWhen()接受一个闭包,闭包内检查某个选项的$value是否需要被禁用:

use Filament\Forms\Components\Radio; Radio::make('status') ->options([ 'draft' => 'Draft', 'scheduled' => 'Scheduled', 'published' => 'Published', ]) ->disableOptionWhen(fn (string $value): bool => $value === 'published')

闭包可注入两个参数:

参数类型说明
$valuemixed当前待判断选项的值
$labelstring \| Illuminate\Contracts\Support\Htmlable当前待判断选项的标签

实现位于 Concerns/CanDisableOptions.php,其完整签名为disableOptionWhen(bool | Closure | null $callback, bool $merge = false)

  • 默认($merge = false)会覆盖此前的禁用规则;
  • 传入$merge = true时可追加多条禁用规则(isOptionDisabled[] = $callback);
  • isOptionDisabled()逐条evaluate()所有规则,只要有一条命中即视为禁用。

渲染时(Radio.php)被禁用的选项会生成带disabled属性的原生input[type=radio]

获取未禁用的选项做校验:getEnabledOptions()

禁用选项只影响交互,并不自动拦截提交的非法值。若要在校验层同步排除已禁用选项,可结合getEnabledOptions()in()校验规则:

use Filament\Forms\Components\Radio; Radio::make('status') ->options([ 'draft' => 'Draft', 'scheduled' => 'Scheduled', 'published' => 'Published', ]) ->disableOptionWhen(fn (string $value): bool => $value === 'published') ->in(fn (Radio $component): array => array_keys($component->getEnabledOptions()))

getEnabledOptions()(CanDisableOptions.php)会过滤掉所有被禁用规则命中的选项,返回[值 => 标签]数组;测试 RadioTest.php 验证了禁用archived后仅返回activeinactive

实际上Radio组件对选项校验做了更强的自动化:默认状态无需显式调用in()Radio重写了getInValidationRuleValues()(Radio.php),当没有手动指定校验值时,会自动以「未禁用选项的键集合」作为in校验白名单。测试 RadioTest.php 与 L272-L284 均验证:提交被禁用选项值会触发in校验错误,而提交合法值或空值(null)可通过校验。

布尔单选框:boolean()快捷模式

如果只是需要一个简单的「是/否」单选组,boolean()可以直接生成带 Yes / No 两个选项的单选框:

use Filament\Forms\Components\Radio; Radio::make('feedback') ->label('Like this post?') ->boolean()

可通过命名参数自定义两个选项的标签:

Radio::make('feedback') ->label('Like this post?') ->boolean(trueLabel: 'Absolutely!') Radio::make('feedback') ->label('Like this post?') ->boolean(falseLabel: 'Not at all!')

boolean()的实现非常巧妙(Radio.php):

  1. 自动把选项设为[1 => trueLabel, 0 => falseLabel],默认文案取自语言包filament-forms::components.radio.boolean.true / false
  2. 同时注册一个BooleanStateCastisStoredAsInt => true)状态转换器,使得存储层使用整数1 / 0,而组件状态层暴露布尔值true / false

配套的状态细节:

  • getDefaultState()(Radio.php)会把布尔型默认值统一转换为1 / 0(测试见 RadioTest.php);
  • hasNullableBooleanState()恒返回true,表示该布尔状态允许为null(未选择);
  • 未显式设置状态转换器且未绑定枚举时,getDefaultStateCasts()默认返回OptionStateCastisNullable => true),即选项值可空(Radio.php);
  • 测试 RadioTest.php 验证了fillForm(['is_active' => 1])后组件状态为true的整数与布尔双向转换。

渲染原理与无障碍

Radio实现了HasEmbeddedView,通过toEmbeddedHtml()(Radio.php)以内嵌视图方式输出 HTML,无需额外 Blade 模板文件。其渲染结构要点:

  • 容器divrole="radiogroup"aria-labelledby,以及fi-fo-radio类(内联时追加fi-inline);
  • 每个选项是<label>包裹的原生<input type="radio">name统一使用字段 id,value为选项值;
  • 选项文本与描述(若存在)分别渲染为.fi-fo-radio-label-text.fi-fo-radio-label-description
  • 字段整体禁用、单选项禁用、错误状态分别通过disabled属性与fi-valid/fi-invalid类体现。

浏览器级渲染测试(RadioTest.php)会对/radio-test页面执行冒烟测试与无障碍检查(含暗色模式),并验证含双引号的选项值(如1/2" wrench)能被正确转义渲染。

完整示例:一个可运行的资源表单字段

将以上能力组合起来,即可得到一个功能完整的单选字段定义:

use Filament\Forms\Components\Radio; use Filament\Schemas\Schema; public function form(Schema $form): Schema { return $form ->schema([ Radio::make('status') ->label('Post status') ->options([ 'draft' => 'Draft', 'scheduled' => 'Scheduled', 'published' => 'Published', ]) ->descriptions([ 'draft' => 'Not visible to visitors.', 'scheduled' => 'Will become visible on the scheduled date.', 'published' => 'Immediately visible to visitors.', ]) ->default('draft') ->inline(), Radio::make('notify_subscribers') ->label('Notify subscribers?') ->boolean(trueLabel: 'Yes, notify them', falseLabel: 'No, keep it quiet'), ]) ->statePath('data'); }

小结

Radio是 Filament 表单中最常用的单选输入组件之一,围绕它文档与源码共同构成了五个核心能力:静态/动态options()选项、descriptions()选项描述、inline()内联布局、disableOptionWhen()单选项禁用(配合自动化的getInValidationRuleValues()校验白名单),以及内置整数存储与布尔状态转换的boolean()快捷模式。结合 Radio.php 及其 Trait 与 RadioTest.php 中的测试断言,你可以放心地将其接入资源表单、弹窗表单或 Livewire 自定义表单,并获得完整的无障碍与校验保障。

如需了解更多校验规则(如in()的其它用法),可继续阅读 23-validation.md。

【免费下载链接】filamentA powerful open-source UI framework for Laravel • Build and ship apps & admin panels fast with Livewire项目地址: https://gitcode.com/GitHub_Trending/fi/filament

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/9/10 15:53:53

消除游戏-flask sqlite

本项目为前几天收费帮学妹做的一个项目&#xff0c;在工作环境中基本使用不到&#xff0c;但是很多学校把这个当作编程入门的项目来做&#xff0c;故分享出本项目供初学者参考。 一、项目描述 网页版休闲消除游戏 — 霓虹赛博朋克风格 127.0.0.1:5000/ 二、项目功能 – &am…

作者头像 李华
网站建设 2026/9/10 15:52:51

Python异步编程与结构化并发实战解析

1. Python异步编程的现状与挑战在当今互联网应用中&#xff0c;高并发处理能力已经成为衡量系统性能的关键指标。Python作为最受欢迎的编程语言之一&#xff0c;其异步编程模型近年来经历了重大变革。从早期的回调地狱到现在的async/await语法&#xff0c;Python的异步生态已经…

作者头像 李华
网站建设 2026/9/10 15:50:21

CANN/ge创建向量常量API

CreateVector 【免费下载链接】ge GE&#xff08;Graph Engine&#xff09;是面向昇腾的图编译器和执行器&#xff0c;提供了计算图优化、多流并行、内存复用和模型下沉等技术手段&#xff0c;加速模型执行效率&#xff0c;减少模型内存占用。 GE 提供对 PyTorch、TensorFlow 前…

作者头像 李华
网站建设 2026/9/10 15:49:58

荣耀软件客服服务游戏全新升级打造24小时客户退款热线电话

在数字经济与游戏产业深度融合的浪潮中&#xff0c;游戏企业既是数字娱乐体验的创造者&#xff0c;更是合规运营与用户权益的守护者。游科技”&#xff09;自2020年9月成立以来&#xff0c;依托腾讯集团的资源优势&#xff0c;以游戏运营与服务为核心赛道&#xff0c;在多元产品…

作者头像 李华