完全指南:顯示、格式化與交互定制)
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),僅供參考