ARTICLE DETAIL

资讯详情

深耕网站视觉设计与运营推广的一线实战洞察。

Filament Infolists 文本条目(TextEntry)完全指南:显示、格式化与交互定制

Filament Infolists 文本条目(TextEntry)完全指南:显示、格式化与交互定制 Filament Infolists 文本条目TextEntry完全指南显示、格式化与交互定制【免费下载链接】filamentA powerful open-source UI framework for Laravel • Build and ship apps admin panels fast with Livewire项目地址: https://gitcode.com/GitHub_Trending/fi/filamentTextEntry 是 Filament Infolists 包中最基础也最常用的只读展示组件用于在详情页、关系管理器与动作弹窗中显示单条或多条文本数据。本文以 Filament 4.x 的packages/infolists/docs/02-text-entry.md为骨架结合 TextEntry.php 及 CanFormatState.php 等源码实现系统讲解文本条目的颜色、图标、徽章、日期/数字/金额格式化、Markdown/HTML 渲染、多值列表、长文本处理、剪贴板复制与前缀后缀动作等全部能力帮助你在构建 Laravel 后台详情页时精准掌控文本展示的每一个细节。基本用法文本条目通过静态方法make()创建其唯一参数是条目的名字通常对应 Eloquent 模型上的某个属性。把它放进 Infolist 的 schema 组件数组中即可use Filament\Infolists\Components\TextEntry; TextEntry::make(title)条目名字支持点表示法dot notation可以跨关联关系读取属性也可以读取 JSON / 数组列中的键值TextEntry::make(author.name) // 读取 author 关系上的 name 属性 TextEntry::make(meta.title) // 读取 meta JSON 列中的 title 键关于状态state的概念、state()手动传值、default()默认值、placeholder()空值占位、label()标签自定义等 Infolist 通用能力可参见 Infolists 总览。文本条目的所有展示逻辑都建立在状态之上。从源码看TextEntry继承了 Entry.php 并混入了多个 ConcernCanFormatState格式化、HasColor颜色、HasIcon/HasIconColor图标、HasAffixes前后缀、CanBeCopied复制、CanWrap换行、HasFontFamily/HasWeight/HasLineClamp字体与行数控制这也是它能力如此丰富的原因所在。自定义文本颜色使用color()方法可以为文本设置颜色颜色可以是primary、success、warning、danger、gray等主题色也可以传入任意 CSS 颜色use Filament\Infolists\Components\TextEntry; TextEntry::make(status) -color(primary)color()同样接受闭包让你可以根据状态动态计算颜色典型的用法是与下面的徽章模式配合让状态值拥有匹配的语义色详见后文以徽章形式显示一节。从 HasColor.php 的实现看getColor()在求值闭包后如果颜色仍为空且状态对象实现了HasColor接口还会回退调用$state-getColor()——也就是说如果你的模型枚举实现了该接口条目会自动继承其颜色定义。添加图标文本条目可以附带一个图标use Filament\Infolists\Components\TextEntry; use Filament\Support\Icons\Heroicon; TextEntry::make(email) -icon(Heroicon::Envelope)icon()也接受闭包动态计算图标。图标默认显示在文本之前可以通过iconPosition()调整位置use Filament\Infolists\Components\TextEntry; use Filament\Support\Enums\IconPosition; use Filament\Support\Icons\Heroicon; TextEntry::make(email) -icon(Heroicon::Envelope) -iconPosition(IconPosition::After) // IconPosition::Before默认或 IconPosition::After图标颜色默认继承文本颜色如需单独定制可使用iconColor()use Filament\Infolists\Components\TextEntry; use Filament\Support\Icons\Heroicon; TextEntry::make(email) -icon(Heroicon::Envelope) -iconColor(primary)从 TextEntry.php 的渲染逻辑toEmbeddedHtml()可以看到图标最终通过generate_icon_html()生成并且图标尺寸会跟随文本尺寸联动TextSize::Medium对应中等图标、TextSize::Large对应大图标其余情况使用小图标。以徽章Badge形式显示默认的纯文本没有背景色。通过badge()可以把文本渲染成带背景色的徽章最常见的应用场景是状态展示——配合color()让不同状态拥有语义色use Filament\Infolists\Components\TextEntry; TextEntry::make(status) -badge() -color(fn (string $state): string match ($state) { draft gray, reviewing warning, published success, rejected danger, })徽章上还可以叠加图标见上文添加图标一节。badge()也可接收布尔值或返回布尔值的闭包来动态控制是否启用徽章样式TextEntry::make(status) -badge(FeatureFlag::active())在源码中徽章由$isBadge属性驱动TextEntry.php渲染时会给条目加上fi-in-text-has-badges样式类并使用BadgeComponent组件着色。格式化显示内容文本条目从模型自动取到的原始值state未必适合直接展示。formatStateUsing()可以在不改动原始数据的前提下把状态格式化成更友好的文本——这在多语言应用中非常实用use Filament\Infolists\Components\TextEntry; TextEntry::make(status) -formatStateUsing(fn (string $state): string __(statuses.{$state}))例如数据库中的status列存放draft、reviewing、published、rejected等值界面展示的则是翻译后的文本。formatStateUsing()的函数同样支持注入各种工具参数见文末工具注入。除了手写闭包Filament 还内置了一系列一键格式化方法。它们的底层统一实现在 CanFormatState.php 的formatState()方法中该方法先求值formatStateUsing闭包再依次处理数组序列化、HTML/富文本、字符数与单词数截断、前后缀拼接等环节。日期格式化使用date()、dateTime()、time()方法可以直接基于 PHP 日期格式化令牌 格式化状态use Filament\Infolists\Components\TextEntry; TextEntry::make(created_at)-date() TextEntry::make(created_at)-dateTime() TextEntry::make(created_at)-time()三个方法都接受自定义格式字符串TextEntry::make(created_at)-date(M j, Y) TextEntry::make(created_at)-dateTime(M j, Y H:i:s) TextEntry::make(created_at)-time(H:i:s)格式化字符串同样可以传入闭包动态计算。从 CanFormatState.php 的date()实现看其内部是Carbon::parse($state)-setTimezone(...)-translatedFormat($format)并使用容器的默认日期显示格式作为兜底。使用 Carbon 宏格式isoDate()、isoDateTime()、isoTime()方法则使用 Carbon 的宏格式如L、LLL、LTuse Filament\Infolists\Components\TextEntry; TextEntry::make(created_at)-isoDate() TextEntry::make(created_at)-isoDateTime() TextEntry::make(created_at)-isoTime() // 传入自定义宏格式字符串 TextEntry::make(created_at)-isoDate(L) TextEntry::make(created_at)-isoDateTime(LLL) TextEntry::make(created_at)-isoTime(LT)相对时间格式化since()方法基于 Carbon 的diffForHumans()把时间渲染为相对时间如3 分钟前use Filament\Infolists\Components\TextEntry; TextEntry::make(created_at) -since()在悬浮提示Tooltip中显示格式化日期下面这些方法可以把格式化后的日期放进悬浮提示里常与since()这类信息压缩型展示搭配为用户补充精确时间use Filament\Infolists\Components\TextEntry; TextEntry::make(created_at) -since() -dateTooltip() // 接受自定义 PHP 日期格式字符串 TextEntry::make(created_at) -since() -dateTimeTooltip() // 接受自定义 PHP 日期格式字符串 TextEntry::make(created_at) -since() -timeTooltip() // 接受自定义 PHP 日期格式字符串 TextEntry::make(created_at) -since() -isoDateTooltip() // 接受自定义 Carbon 宏格式字符串 TextEntry::make(created_at) -since() -isoDateTimeTooltip() // 接受自定义 Carbon 宏格式字符串 TextEntry::make(created_at) -since() -isoTimeTooltip() // 接受自定义 Carbon 宏格式字符串 TextEntry::make(created_at) -dateTime() -sinceTooltip()源码中这些*Tooltip()方法本质上都是调用tooltip()方法并传入一个格式化闭包CanFormatState.php。设置日期格式化时区所有日期格式化方法都接受timezone参数用于把状态中的时间转换到目标时区use Filament\Infolists\Components\TextEntry; TextEntry::make(created_at) -dateTime(timezone: America/New_York)也可以使用timezone()方法一次性为条目上的所有日期时间格式化方法设置时区TextEntry::make(created_at) -timezone(America/New_York) -dateTime()如果条目没有单独指定时区则使用 Filament 的默认时区。可以在服务提供者如AppServiceProvider的boot()方法中通过FilamentTimezone::set()全局设置默认时区use Filament\Support\Facades\FilamentTimezone; public function boot(): void { FilamentTimezone::set(America/New_York); }这在需要为应用中所有文本条目统一默认时区时非常有用Filament 中其他涉及时区的场景也复用该设置。注意Filament 的默认时区只在条目存储了时间时才生效。如果条目只存储日期使用date()而非dateTime()时区不会应用——这是为了避免存储无时间日期时发生时区偏移CanFormatState.php 中getTimezone()也印证了这一点仅当isDateTime()为真时才使用FilamentTimezone::get()否则回退到config(app.timezone)。数字格式化numeric()方法把条目渲染为按本地化规则格式化的数字use Filament\Infolists\Components\TextEntry; TextEntry::make(stock) -numeric()可通过decimalPlaces参数指定小数位TextEntry::make(stock) -numeric(decimalPlaces: 0)默认使用应用 locale 进行数字格式化也可通过locale参数指定TextEntry::make(stock) -numeric(locale: nl)decimalPlaces与locale均支持闭包动态计算。从源码看numeric()在未显式指定分隔符时走Number::format()的本地化路径若传入自定义decimalSeparator/thousandsSeparator如ArgumentValue::Default之外的值则改用 PHP 的number_format()CanFormatState.php。金额格式化money()方法可以按任意货币格式化金额use Filament\Infolists\Components\TextEntry; TextEntry::make(price) -money(EUR)divideBy参数允许在格式化前先除以一个数——例如数据库以分存储价格时非常实用TextEntry::make(price) -money(EUR, divideBy: 100)同样支持locale与decimalPlaces参数TextEntry::make(price) -money(EUR, locale: nl) TextEntry::make(price) -money(EUR, decimalPlaces: 3)money()的底层通过Number::currency($state, $currency, $locale, $decimalPlaces)实现货币与 locale 缺省时分别回退到容器默认货币与应用 localeCanFormatState.php。所有参数同样支持闭包。渲染 Markdown如果条目值是 Markdown 文本可以使用markdown()渲染use Filament\Infolists\Components\TextEntry; TextEntry::make(description) -markdown()同样支持布尔参数或闭包动态开关TextEntry::make(description) -markdown(FeatureFlag::active())渲染 HTML如果条目值是 HTML可以使用html()渲染use Filament\Infolists\Components\TextEntry; TextEntry::make(description) -html()同样支持布尔参数或闭包TextEntry::make(description) -html(FeatureFlag::active())安全提示Filament 内置的 HTML 清理器为了支持富文本格式如字体颜色、文本高亮、图片尺寸允许内联style属性。这意味着background: url(...)或position: fixed这类 CSS 属性不会被从清理后的 HTML 中剔除。如果内容来自不受信任的用户应考虑收紧默认配置具体见 安全文档即 高级·安全。源码中html()与markdown()的注释也明确记录了这一点CanFormatState.php两者最终都会走Str::sanitizeHtml()。渲染未经清理的原始 HTML如果你确实需要跳过清理可以把 HTML 包装成HtmlString对象返回use Filament\Infolists\Components\TextEntry; use Illuminate\Support\HtmlString; TextEntry::make(description) -formatStateUsing(fn (string $state): HtmlString new HtmlString($state))危险渲染原始 HTML 可能包含恶意内容导致 XSS 等安全漏洞。使用前务必确保渲染的 HTML 是安全的。另一种绕过清理的方式是从formatStateUsing()中返回view()对象视图渲染结果同样不会被清理use Filament\Infolists\Components\TextEntry; use Illuminate\Contracts\View\View; TextEntry::make(description) -formatStateUsing(fn (string $state): View view( filament.infolists.components.description-entry-content, [state $state], ))展示多个值当条目状态是数组时例如 Eloquent 属性使用了arraycast、关联关系返回多条结果或通过state()传入了数组文本条目会以逗号分隔渲染多个值。使用listWithLineBreaks()可以让每个值独占一行use Filament\Infolists\Components\TextEntry; TextEntry::make(authors.name) -listWithLineBreaks()同样支持布尔/闭包参数TextEntry::make(authors.name) -listWithLineBreaks(FeatureFlag::active())从 TextEntryTest.php 的测试可以看到多个值Tag 1、Tag 2、Tag 3都能被正确渲染而isListWithLineBreaks()在设置了bulleted()时也会返回true。为列表添加项目符号bulleted()方法为每个列表项添加项目符号TextEntry::make(authors.name) -bulleted()同样支持布尔/闭包参数TextEntry::make(authors.name) -bulleted(FeatureFlag::active())限制列表项数量limitList()可以限制最多显示的列表项个数TextEntry::make(authors.name) -listWithLineBreaks() -limitList(3)展开被限制的列表expandableLimitedList()允许用户展开/收起被截断的列表TextEntry::make(authors.name) -listWithLineBreaks() -limitList(3) -expandableLimitedList()该功能仅对listWithLineBreaks()或bulleted()生效因为这两种模式下每个条目独占一行。同样支持布尔/闭包参数TextEntry::make(authors.name) -listWithLineBreaks() -limitList(3) -expandableLimitedList(FeatureFlag::active())源码层面限制列表的逻辑在 TextEntry.php先计算超出数量的条目数若不可展开则直接用array_slice()截断可展开时则保留全部数据通过 Alpine.js 的x-show/isLimited状态控制显隐并渲染展开/收起链接使用trans_choice()处理单复数文案。把单个值按分隔符拆分成多个列表项separator()方法可以把模型中的一段文本按分隔符拆分成多个列表项——例如把逗号分隔的标签渲染成徽章use Filament\Infolists\Components\TextEntry; TextEntry::make(tags) -badge() -separator(,)聚合关联关系Filament 为文本条目提供了关系聚合方法avg()、max()、min()、sum()。例如想展示某个关联下所有记录某字段的平均值use Filament\Infolists\Components\TextEntry; TextEntry::make(users_avg_age)-avg(users, age)这里users是关联名age是被聚合的字段。条目名必须写成users_avg_age这种约定格式——这正是 Laravel 聚合函数 存储结果的命名规范。从源码看avg()内部通过$record-loadAvg($relationship, $column)加载聚合值再读取条目名对应的属性TextEntry.phpcounts()、max()、min()、sum()分别对应loadCount()/loadMax()/loadMin()/loadSum()。如果需要在聚合前对关联查询做约束可以传入数组键为关联名、值为作用域闭包use Filament\Infolists\Components\TextEntry; use Illuminate\Database\Eloquent\Builder; TextEntry::make(users_avg_age)-avg([ users fn (Builder $query) $query-where(is_active, true), ], age)自定义文本大小文本条目默认使用小号字体可通过size()切换为TextSize::ExtraSmall、TextSize::Medium或TextSize::Largeuse Filament\Infolists\Components\TextEntry; use Filament\Support\Enums\TextSize; TextEntry::make(title) -size(TextSize::Large)从 TextSize.php 可以看到枚举值ExtraSmall xs、Small sm默认、Medium md、Large lgTextEntry.php 的getSize()会先把闭包求值空值回退到TextSize::Small字符串base则映射为TextSize::Medium。自定义字体粗细默认字重为常规regular可通过weight()切换为以下选项FontWeight::Thin、FontWeight::ExtraLight、FontWeight::Light、FontWeight::Medium、FontWeight::SemiBold、FontWeight::Bold、FontWeight::ExtraBold、FontWeight::Black。例如加粗use Filament\Infolists\Components\TextEntry; use Filament\Support\Enums\FontWeight; TextEntry::make(title) -weight(FontWeight::Bold)weight()也接受闭包动态计算。自定义字体族fontFamily()可以切换字体族选项包括FontFamily::Sans、FontFamily::Serif、FontFamily::Mono。例如把 API 密钥渲染为等宽字体use Filament\Support\Enums\FontFamily; use Filament\Infolists\Components\TextEntry; TextEntry::make(apiKey) -label(API key) -fontFamily(FontFamily::Mono)同样接受闭包动态计算。处理长文本限制文本长度limit()可以限制条目值的字符数use Filament\Infolists\Components\TextEntry; TextEntry::make(description) -limit(50)默认截断后追加省略号...可通过end参数自定义TextEntry::make(description) -limit(50, end: (more))limit()和end都支持闭包。你还可以在闭包里通过getCharacterLimit()复用传入limit()的值——例如结合tooltip()实现内容超长时才显示完整文本悬浮提示use Filament\Infolists\Components\TextEntry; TextEntry::make(description) -limit(50) -tooltip(function (TextEntry $component): ?string { $state $component-getState(); if (strlen($state) $component-getCharacterLimit()) { return null; } // 仅当条目内容超过长度限制时才渲染悬浮提示 return $state; })限制单词数words()可以限制显示的单词数量TextEntry::make(description) -words(10)同样支持end参数自定义截断后缀TextEntry::make(description) -words(10, end: (more))从 CanFormatState.php 看limit()与words()分别存储字符限制和单词限制最终在formatState()中通过Str::limit()与Str::words()执行截断。限制文本行数lineClamp()把文本限制为固定行数超出的部分被裁剪。这在响应式界面中特别有用可以保证不同屏幕尺寸下体验一致TextEntry::make(description) -lineClamp(2)渲染时行数通过 CSS 自定义属性--line-clamp注入TextEntry.php。禁止文本换行默认文本超出容器宽度时会换行wrap(false)可以禁止换行TextEntry::make(description) -wrap(false)TextEntry的默认行为是允许换行的源码中canWrapByDefault()返回true见 TextEntry.php。允许一键复制到剪贴板copyable()让文本可点击复制到剪贴板并可自定义确认消息与显示时长毫秒use Filament\Infolists\Components\TextEntry; TextEntry::make(apiKey) -label(API key) -copyable() -copyMessage(Copied!) -copyMessageDuration(1500)同样支持布尔/闭包参数动态控制TextEntry::make(apiKey) -label(API key) -copyable(FeatureFlag::active())copyable()、copyMessage()、copyMessageDuration()均支持闭包。底层通过CanBeCopiedconcern 实现渲染时使用window.navigator.clipboard.writeText()写入剪贴板并用$tooltip()弹出确认消息TextEntry.php。注意该功能仅在应用启用 SSL 时可用浏览器对剪贴板 API 的安全上下文要求。添加前缀与后缀动作可以使用prefixAction()和suffixAction()在条目前后放置动作按钮与prefix()/suffix()纯文本前后缀配合使用。例如给价格条目加一个复制到 Price的动作use Filament\Actions\Action; use Filament\Infolists\Components\TextEntry; use Filament\Support\Icons\Heroicon; TextEntry::make(cost) -prefix(€) -suffixAction( Action::make(copyCostToPrice) -icon(Heroicon::Clipboard), )从 HasAffixes.php 的实现看前后缀动作支持传入单个动作或动作数组且最终都会被强制应用Size::Small与Action::ICON_BUTTON_VIEW即渲染为小号图标按钮。prefix()与suffix()纯文本在 CanFormatState.php 的formatState()末尾统一拼接到状态两侧。更多工具注入与全局配置与 Infolist 其他条目一致TextEntry 的绝大多数配置方法都接受闭包并能通过参数注入多种工具$state、$record、$component、$livewire、$get、$operation等详见 Infolists 总览 的Entry utility injection一节。此外可以通过configureUsing()在服务提供者的boot()方法中全局修改所有TextEntry的默认行为例如让所有文本条目默认words(10)再在单个条目上用words(null)覆盖。相关阅读Infolists 总览与条目通用能力图标条目 IconEntry颜色样式系统图标使用指南安全与 HTML 清理器定制核心实现TextEntry.php、CanFormatState.php测试验证TextEntryTest.php【免费下载链接】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),仅供参考
返回列表