Gutenberg 块编辑器中的 FontSizePicker 组件:从基础用法到源码级实现解析
2026/9/17 8:07:43 网站建设 项目流程

Gutenberg 块编辑器中的 FontSizePicker 组件:从基础用法到源码级实现解析

【免费下载链接】gutenbergThe Block Editor project for WordPress and beyond. Plugin is available from the official repository.项目地址: https://gitcode.com/GitHub_Trending/gu/gutenberg

关联文档:packages/block-editor/src/components/font-sizes/README.md

导读

FontSizePicker是 Gutenberg(WordPress 块编辑器)中负责字号选择交互的核心 React 组件,它让用户在预设字号与自定义字号之间自由切换。本文将以@wordpress/block-editor包内该组件的官方文档为主线,完整覆盖其用法与 Props,并结合仓库源码剖析其与@wordpress/components基础组件的差异、编辑器设置的自动注入机制、字号工具函数与流体排版(fluid typography)的前后端一致性实现。读完本文,你将能够在自己的块(Block)编辑器中正确使用FontSizePicker,并理解字号属性、CSS 类名生成与clamp()流体字号背后的完整链路。

FontSizePicker 是什么

FontSizePicker是一个 React 组件,它渲染一套允许用户选择字号的 UI。其界面由两部分构成:

  • 一组预设(常用)字号选项,例如SmallBig
  • 一个自定义字号入口(在启用该功能时),允许用户直接输入或通过滑块指定任意字号值。

@wordpress/block-editor中,存在一个与@wordpress/components对等的组件。两者的关键区别在于:block-editor 版本不要求调用方显式传入fontSizesdisableCustomFontSizes两个属性——这两个值由编辑器设置(editor settings)自动计算得出。这意味着在块编辑场景中,你只需关心业务相关的valueonChange等少量 Props,字号预设列表会自动从主题/编辑器配置中读取。

基础用法

官方文档给出了一个最小可运行示例,直接使用@wordpress/block-editor导出的FontSizePicker

import { FontSizePicker } from '@wordpress/block-editor'; import { useState } from '@wordpress/element'; import { __ } from '@wordpress/i18n'; const MyFontSizePicker = () => { const [ fontSize, setFontSize ] = useState( 16 ); const fontSizes = [ { name: __( 'Small' ), slug: 'small', size: 12, }, { name: __( 'Big' ), slug: 'big', size: 26, }, ]; const fallbackFontSize = 16; return ( <FontSizePicker value={ fontSize } fallbackFontSize={ fallbackFontSize } onChange={ ( newFontSize ) => { setFontSize( newFontSize ); } } /> ); }; <MyFontSizePicker />

几点使用要点:

  • fontSizes数组中每个对象包含name(显示标签)、slug(唯一标识,用于 CSS 类名生成)、size(字号数值)三个核心字段;
  • fallbackFontSizeonChange共同配合滑块交互(见下文 Props 说明);
  • 在本例中未传fontSizes,组件的预设列表实际来自编辑器设置(typography.fontSizes),这正是 block-editor 版本与 components 版本行为上的核心差异。

组件 Props 详解

文档明确列出了 block-editor 版FontSizePicker接受的 Props,完整信息如下:

fallbackFontSize

当当前没有值时,该属性定义字号选择器滑块的起始位置。仅在withSlidertrue时生效

  • 类型:Number
  • 必填:否

onChange

一个接收新字号值的回调函数。如果onChange被无参数调用,则意味着重置值,具体重置语义由使用方根据上下文决定——例如将字号设置为undefined,或恢复为某个起始值。

  • 类型:function
  • 必填:是

value

当前字号值。

  • 类型:Number
  • 必填:否

withSlider

如果为true,UI 中将显示一个滑块,取代数字文本输入框;如果为false,则不显示滑块。

  • 类型:Boolean
  • 必填:否
  • 默认值:false

由基础组件继承的更多 Props

由于 block-editor 版本质上是对@wordpress/componentsFontSizePicker的薄封装,因此基础组件的全部 Props 同样可用。根据 packages/components/src/font-size-picker/README.md 与 types.ts,其中与编辑器场景高度相关的还包括:

Prop类型默认值说明
fontSizesFontSize[][]预设字号对象数组。对象需包含size(数字 px 值,或形如"13px""1em""clamp(12px, 5vw, 100px)"的字符串 CSS 值)、name(标签)、slug(唯一标识,用于类名生成)。defaultcustom为保留 slug,不可使用
disableCustomFontSizesbooleanfalsetrue时用户无法选择自定义字号,只能从预设字号中挑选
unitsstring[]['px','em','rem','vw','vh']自定义字号可选的单位列表
valueMode'literal' \| 'slug''literal'指定value的解释方式:字面量字号值,或所选字号的 slug
withResetbooleantrue自定义字号激活时,输入框旁是否显示重置按钮;disableCustomFontSizestrue时不生效
__nextHasNoMarginBottombooleanfalse已废弃,自 WP 6.5 起为默认行为

需要特别说明的是units的使用前提:要让units生效,value必须是以带单位字符串形式传入(如'12px');当value为数字时组件运行在"无单位模式",units不产生作用。

源码级剖析:block-editor 版如何自动注入设置

block-editor 版FontSizePicker的实现非常精简,完整代码位于 font-size-picker.jsx:

import { FontSizePicker as BaseFontSizePicker } from '@wordpress/components'; import { useSettings } from '../use-settings'; function FontSizePicker( props ) { const [ fontSizes, customFontSize ] = useSettings( 'typography.fontSizes', 'typography.customFontSize' ); return ( <BaseFontSizePicker { ...props } fontSizes={ fontSizes } disableCustomFontSizes={ ! customFontSize } /> ); }

它通过useSettings钩子一次性读取两个编辑器设置路径,并自动映射为底层组件的两个 Props:

  • typography.fontSizesfontSizes(预设字号列表);
  • typography.customFontSizedisableCustomFontSizes的取反(即当自定义字号被禁用时,直接透传disableCustomFontSizes={ true })。

useSettings的实现见 use-settings/index.js:它基于当前块实例(useBlockEditContext提供的clientId)调用getBlockSettings查找设置——先在块实例层级(Block Instance)的设置中查找,找不到再回退到块编辑器设置(Block Editor Settings)。这保证了主题定义的settings.typography.fontSizes能正确到达组件。

字号工具函数:属性解析与 CSS 类名

packages/block-editor/src/components/font-sizes/目录下除了组件本身,还提供了一组与字号处理相关的纯函数(见 utils.js),这些函数在块属性与最终渲染结果之间起到桥梁作用:

getFontSize( fontSizes, fontSizeAttribute, customFontSizeAttribute )

根据命名字号属性(slug)自定义字号属性(数值)解析出最终字号对象:

  • fontSizeAttribute存在且在fontSizes中命中相同 slug,返回该字号对象;
  • 否则返回{ size: customFontSizeAttribute },即回退到自定义字号值。

getFontSizeObjectByValue( fontSizes, value )

根据数值查找对应的字号对象;未命中时返回{ size: value }

getFontSizeClass( fontSizeSlug )

根据字号 slug 生成 CSS 类名,规则是has-前缀 + kebab-case 化的 slug +-font-size后缀。例如:

  • '14px'has-14-px-font-size
  • 16has-16-font-size
  • '#abcdef'has-abcdef-font-size

这些行为在 test/utils.js 中都有对应的 Vitest 用例验证,例如Should return the correct font size class when given a string断言getFontSizeClass( '14px' )等于'has-14-px-font-size'

withFontSizes 高阶组件

目录中还包含一个高阶组件 with-font-sizes.jsx,用于把字号逻辑注入块组件:它会自动读取typography.fontSizes设置,为被包裹组件提供fontSizes属性,并根据传入的字号属性名(如'fontSize')自动生成:

  • 对应的自定义字号属性名(约定为custom+ 首字母大写的属性名,如customFontSize);
  • setFontSize之类的 setter 方法——调用时若新值能命中预设字号则写入 slug,否则写入自定义字号值;
  • 通过getDerivedStateFromProps同步解析出包含sizeclass的当前字号对象。

这在类似"段落块"这类同时具备预设与自定义字号语义的块中非常常见。

流体排版(Fluid Typography)的前后端一致性

FontSizePicker的选择结果最终会被渲染为 CSSfont-size。当主题启用了流体排版(settings.typography.fluid)时,字号会被转换为clamp()表达式。这一逻辑在前端与后端各有一套实现,且必须保持一致:

  • 前端:packages/block-editor/src/components/font-sizes/fluid-utils.js中的getComputedFluidTypographyValue()
  • 后端:lib/block-supports/typography.php中的gutenberg_get_typography_font_size_value()

fluid-utils.js文件头部有明确注释说明这一对应关系,并定义了整套默认参数:

const DEFAULT_MAXIMUM_VIEWPORT_WIDTH = '1600px'; const DEFAULT_MINIMUM_VIEWPORT_WIDTH = '320px'; const DEFAULT_SCALE_FACTOR = 1; const DEFAULT_MINIMUM_FONT_SIZE_FACTOR_MIN = 0.25; const DEFAULT_MINIMUM_FONT_SIZE_FACTOR_MAX = 0.75; const DEFAULT_MINIMUM_FONT_SIZE_LIMIT = '14px';

getComputedFluidTypographyValue的核心用法(见 fluid-utils.js):

// 给定最小与最大字号,计算流体字号。 const fontSize = getComputedFluidTypographyValue( { minimumFontSize: '20px', maximumFontSize: '45px', } ); // 只给单个字号,按对数比例尺自动推导上下限。 const fontSize = getComputedFluidTypographyValue( { fontSize: '30px', } );

其输出形如clamp(14px, 3.3px + 2.1vw, 36px),即 CSS 原生clamp()表达式。函数内部还借助getTypographyValueAndUnit完成单位归一化(默认支持rempxem,纯数值按px处理,rem/empx之间按rootSizeValue = 16换算),并对非法单位、无效视口区间等边界情况返回null以保护性降级。

后端的gutenberg_get_typography_font_size_value()(见 lib/block-supports/typography.php 附近)实现了几乎一致的算法:同样归一化单位、计算线性因子并输出clamp()表达式。这种"前后端双实现 + 注释互相对齐"的设计,保证了编辑器预览与前端渲染结果完全一致。

在实际块中使用

综合以上内容,一个典型的块编辑器中字号控制器的组合方式如下:

import { FontSizePicker, getFontSizeClass } from '@wordpress/block-editor'; // 在块 edit 中: <FontSizePicker value={ attributes.fontSize } fallbackFontSize={ 16 } withSlider onChange={ ( nextValue ) => { // 无参数调用表示重置 if ( nextValue === undefined ) { setAttributes( { fontSize: undefined } ); return; } setAttributes( { fontSize: nextValue } ); } } />

同时,在save端或服务端渲染端,通过getFontSizeClass( attributes.fontSize )生成如has-small-font-size的类名,配合主题 CSS 完成最终样式输出;若启用了流体排版,字号值还会被前后端一致的clamp()计算逻辑处理,确保响应式缩放。

总结

  • @wordpress/block-editorFontSizePicker是对@wordpress/components基础组件的封装,自动从编辑器设置注入fontSizesdisableCustomFontSizes,降低了块开发者的使用门槛;
  • 其核心 Props(fallbackFontSizeonChangevaluewithSlider)与基础组件继承的 Props(fontSizesunitsvalueModewithReset等)共同覆盖了预设选择、自定义输入、滑块调节与重置的完整交互;
  • 配套的 utils.js、with-font-sizes.jsx 与 fluid-utils.js 分别负责字号解析、类名生成、高阶注入与流体字号计算,构成了一套完整的字号控制体系;
  • 流体排版的算法在 lib/block-supports/typography.php 中有对等的 PHP 实现,前后端保持一致,是 Gutenberg 架构中"编辑器与渲染结果一致"原则的典型体现。

相关源码文件索引:

  • font-size-picker.jsx:block-editor 版组件封装
  • utils.js:字号解析与类名工具函数
  • with-font-sizes.jsx:字号高阶组件
  • fluid-utils.js:前端流体字号计算
  • test/utils.js:工具函数测试
  • packages/components/src/font-size-picker/types.ts:基础组件 Props 类型定义
  • packages/block-editor/src/components/use-settings/index.js:useSettings设置读取钩子
  • lib/block-supports/typography.php:后端流体字号实现

【免费下载链接】gutenbergThe Block Editor project for WordPress and beyond. Plugin is available from the official repository.项目地址: https://gitcode.com/GitHub_Trending/gu/gutenberg

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

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询