资讯动态

Gutenberg FontSizePicker 组件详解:实现 WordPress 块编辑器中的字号预设与自定义字号选择

发布时间:2026/9/17 5:12:41 来源:尧图企业网站定制
Gutenberg FontSizePicker 组件详解实现 WordPress 块编辑器中的字号预设与自定义字号选择【免费下载链接】gutenbergThe Block Editor project for WordPress and beyond. Plugin is available from the official repository.项目地址: https://gitcode.com/GitHub_Trending/gu/gutenbergFontSizePicker 是 GutenbergWordPress 块编辑器wordpress/components包中的一个受控 React 组件用于在块编辑器的侧边栏检查器中提供字号选择 UI用户可以挑选一组预定义常见字号也可以在该功能开启时输入任意自定义字号。它由 README 定义契约由 index.tsx 实现覆盖 ToggleGroup / Select / 自定义输入三种形态的自动切换、带单位的输入解析、滑块与重置等完整能力。读完本文你将掌握该组件的全部 Props 语义、三种渲染形态的切换条件、单位模式unitless vs. units的判定规则以及在自定义块检查器中正确接入受控字号选择的完整做法。一、组件定位与基本用法组件源码入口为 index.tsx它通过forwardRef导出见该文件第 261-263 行渲染根节点是一个带aria-labelledby标签的fieldset容器styles.ts 中Container styled.fieldset保证无障碍语境下字号选择区域有可访问的名称。官方 README 给出的标准用法如下import { useState } from react; import { FontSizePicker } from wordpress/components; import { __ } from wordpress/i18n; const fontSizes [ { name: __( Small ), slug: small, size: 12, }, { name: __( Big ), slug: big, size: 26, }, ]; const fallbackFontSize 16; const MyFontSizePicker () { const [ fontSize, setFontSize ] useState( 12 ); return ( FontSizePicker fontSizes{ fontSizes } value{ fontSize } fallbackFontSize{ fallbackFontSize } onChange{ ( newFontSize ) { setFontSize( newFontSize ); } } / ); }; ... MyFontSizePicker /要点fontSizes是字号预设数组value是受控的当前字号onChange是唯一必选回调fallbackFontSize仅在withSlider为true时生效作为滑块的初始位置仓库中该组件的 Storybook 示例位于 stories 目录浏览器测试位于 test 目录可作为行为验证的参考。二、Props 完整参考以下逐项覆盖 README 中声明的 Props并结合 types.ts 与 index.tsx 中的默认值解构交叉印证。disableCustomFontSizes:boolean必填否默认false。为true时用户无法选择自定义字号只能从fontSizes预设中挑选。源码中它同时控制两处行为index.tsx头部“Set custom size / Use size preset”切换按钮仅在! disableCustomFontSizes时渲染第 118 行即禁止自定义后用户无法进入自定义输入态当fontSizes.length 0 disableCustomFontSizes时组件直接return null第 87-89 行——既没有预设又禁止自定义则没有任何可交互内容可显示。fallbackFontSize:number必填否。当不存在value时它定义字号滑块的起始位置仅在withSlider为true时相关。从源码看它被原样传给RangeControl的initialPositionindex.tsx只影响滑块的初始值不影响输入框。fontSizes:FontSize[]必填否默认[]。字号对象数组。size为字号值可以是px数字也可以是字号 CSS 值字符串如13px、1em、clamp(12px, 5vw, 100px)name是该字号的显示标签slug是字符串形式的唯一标识用于类名生成。注意default与custom两个 slug 是保留值不可使用。FontSize的完整 TS 类型types.tsexport type FontSize { // 字号值px 数字或 13px、1em、clamp(12px, 5vw, 100px) 等 CSS 值字符串 size: number | string; // 显示标签例如 Small name?: string; // 唯一标识用于类名生成default / custom 为保留 slug slug: string; // 可选提示文本例如流式排版范围说明 hint?: string; };其中hint是 README 未提及但源码支持的可选属性utils.ts 的generateFontSizeHint优先使用调用方提供的hint否则当size是“简单 CSS 值”时回退显示该值本身让 Select 选项在名称下方呈现具体数值。onChange:( value: number | string | undefined, selectedItem?: FontSize ) void必填是。接收新的字号值。若被无参调用或传入undefined应当视为“重置”把字号置为undefined或恢复为起始值。第二个参数selectedItem是触发变更的FontSize预设对象仅在用户选中预设项时提供。units:string[]必填否默认[ px, em, rem, vw, vh ]。自定义字号输入时可选的单位列表。默认值在 index.tsx 中定义为DEFAULT_UNITS并通过useCustomUnits传入UnitControl第 45-47 行。关键前提README 强调units只在value是“带单位字符串”时才起作用若value是纯数字组件进入“unitless mode”units不生效。value:number | string必填否。当前字号值。为undefined时内部视作未选择同时会使 Reset 按钮禁用见下文。valueMode:literal | slug必填否默认literal。决定value的解释方式literalvalue是字号的实际值数字或字符串slugvalue是所选预设的 slug。源码实现要点index.tsxliteral模式按fontSize.size value精确匹配slug模式按fontSize.slug value匹配判定是否处于“自定义值”状态const isCustomValue !! value ! selectedFontSize;第 62 行——value非空且在预设列表中找不到对应项初始就进入自定义输入形态slug模式下自定义控件显示的数值会被解析为该 slug 对应预设的真实sizeresolvedValueForControls第 72-73 行保证用户点击“Set custom size”后输入框能正确预填充。withReset:boolean必填否默认true。为true时自定义字号激活状态下会在输入框旁显示 Reset 按钮当disableCustomFontSizes为true时无效果。Reset 按钮的行为index.tsx{ withReset ( FlexItem Button disabled{ isDisabled } // value undefined 时禁用 accessibleWhenDisabled onClick{ () { onChange?.( undefined ); // 无参调用 onChange 即“重置” } } ... { __( Reset ) } /Button /FlexItem ) }即 Reset 就是调用onChange( undefined )由消费者决定具体重置语义。withSlider:boolean必填否默认false。为true时自定义字号激活状态下会显示滑块disableCustomFontSizes为true时无效果。滑块的参数从源码可以读出完整的取值规则index.tsx参数取值说明min0固定max100或10当前单位是em/rem/vw/vh之一相对单位时为10否则100step1或0.1相对单位为0.1绝对单位px 等为1initialPositionfallbackFontSize滑块初始值withInputFieldfalse滑块自带输入框被隐藏输入由旁边的UnitControl负责滑块onChange在单位模式下会把数量拼回当前单位newValue ( valueUnit ?? px )无单位模式则直接返回数字。三、核心渲染逻辑三种形态的自动切换FontSizePicker 内部把 UI 分为三种形态由currentPickerType决定index.tsxlet currentPickerType; if ( ! disableCustomFontSizes userRequestedCustom ) { // 处于自定义输入形态 currentPickerType custom as const; } else { // 预设数量超过 5 个时降级为 Select否则用 ToggleGroup currentPickerType fontSizes.length MAX_TOGGLE_GROUP_SIZES ? ( select as const ) : ( togglegroup as const ); }其中MAX_TOGGLE_GROUP_SIZES 5index.tsx。即togglegroup预设 ≤ 5 个渲染 FontSizePickerToggleGroup用 T 恤尺码缩写展示select预设 5 个渲染 FontSizePickerSelect用下拉选项列表展示custom用户请求自定义且未禁止自定义渲染UnitControl输入 可选滑块 可选 Reset。ToggleGroup 形态T 恤标签与歧义保护font-size-picker-toggle-group.tsx 用ToggleGroupControl渲染按钮组按钮标签来自 constants.ts 中的T_SHIRT_ABBREVIATIONSS、M、L、XL、XXL并通过aria-label提供完整名称fontSize.name或T_SHIRT_NAMES全名与 tooltip。注释说明其前提假设“当字号数量不超过 5 个时认为它们按大小排序因此显示 T 恤标签”。源码中还有一处重要的歧义保护literal模式下若多个预设的size相同无法区分用户实际选中的是哪个于是返回undefined而不选中任何按钮font-size-picker-toggle-group.tsx// If there are multiple matches, return undefined to avoid selecting the wrong font size if ( matchingFontSizes.length 1 ) { return undefined; }这提示调用方在literal模式下应保证size值的唯一性或改用valueModeslug以 slug 作为唯一标识。Select 形态Default 选项与 hint 展示font-size-picker-select.tsx 在选项列表首位固定插入一个保留选项const DEFAULT_OPTION: FontSizePickerSelectOption { key: default, name: __( Default ), value: undefined, };选择它等价于“重置为默认”onChange( undefined )。这就是保留 slugdefault的原因custom同样保留供消费者表示自定义值。每个预设选项的hint由generateFontSizeHint生成见上文hint说明并由 styles.ts 中的StyledCustomSelectControl强制名称与 hint 换行显示同时右侧保留选中勾号。浏览器测试 font-size-picker-select.browser.test.tsx 对该形态有专门覆盖。浏览器测试还验证了预设数量触发切换的边界with 5 homogeneous font sizes用例提供 6 个字号后断言出现combobox角色、选项总数为 76 个预设 Default 项见 test/index.browser.test.tsx。四、单位模式unitless 与带单位模式这是使用中最容易踩坑的部分。index.tsx 的判定逻辑// If neither the value or first font size is a string, then FontSizePicker // operates in a legacy unitless mode where UnitControl can only be used // to select px values and onChange() is always called with number values. const hasUnits typeof resolvedValueForControls string || typeof fontSizes[ 0 ]?.size string;即“是否启用单位模式”由两个条件之一决定当前value是字符串或第一个预设字号的size是字符串。随后输入值经parseQuantityAndUnitFromRawValue解析为数量与单位两部分第 98-101 行unitless模式下UnitControl的units传入空数组第 203 行units{ hasUnits ? units : [] }onChange用parseInt输出数字单位模式下原样输出字符串相对单位的判定[ em, rem, vw, vh ].includes( valueUnit )第 102-103 行驱动滑块的max/step变化。浏览器测试用参数化用例锁定了这一契约test/index.browser.test.tsx初始值为12px时输入80得到80px初始值为12数字时得到数字80“清除输入框 逐键输入”共触发 3 次onChange1 次清除 2 次按键。另外utils.ts 中isSimpleCssValue的正则界定了“简单 CSS 值”的范围const sizeRegex /^[\d\.](px|em|rem|vw|vh|%|svw|lvw|dvw|svh|lvh|dvh|vi|svi|lvi|dvi|vb|svb|lvb|dvb|vmin|svmin|lvmin|dvmin|vmax|svmax|lvmax|dvmax)?$/i;它决定 hint 回退是否展示原始数值像clamp(12px, 5vw, 100px)这类复合值不算简单 CSS 值源码注释解释部分主题用 CSS 变量无法计算就不展示此时必须依靠调用方提供的hint给用户可读信息。五、状态流转与“自定义值”检测组件内部只有一个核心状态userRequestedCustomindex.tsx初始值由isCustomValue推导const isCustomValue !! value ! selectedFontSize; const [ userRequestedCustom, setUserRequestedCustom ] useState( isCustomValue );由此得到完整流转外部value不在预设中→ 初始即显示自定义输入形态无需点击切换按钮用户点击头部“Set custom size”HeaderToggle带settings图标isPressed表示当前是否处于自定义态→ 切换到custom形态再点击变为“Use size preset”切回预设形态在UnitControl中修改输入、拖动滑块→ 持续setUserRequestedCustom( true )保持自定义形态并把每次输入通过onChange抛给消费者清空UnitControl→ 空字符串按重置处理调用onChange( undefined )第 190-194 行在 Select 中选中预设项→ 通过预设的size值回调若为default保留项则回调undefined。消费者需要注意组件不做持久化重置语义完全由onChange( undefined )的接收方定义README 原文“should reset the value, attending to what reset means in that context”。六、接入建议与注意事项结合上文源码事实实际接入时的检查清单保证 slug 唯一且避开保留字default、custom保留literal模式下还应注意size值的唯一性ToggleGroup 的歧义保护会拒绝选中。单位模式的一致性想让units生效value必须是带单位字符串如12px而非12或至少让fontSizes[0].size为字符串混合数字与字符串会导致hasUnits按value类型动态判定。valueModeslug的适用场景当块属性以 slug 存储如 theme.json 字体预设的slug时用 slug 模式可直接受控组件内部会把 slug 解析为真实size预填充自定义输入resolvedValueForControls。withSlider与fallbackFontSize配套使用fallbackFontSize仅映射到滑块的initialPosition不传时滑块无初始值语义。无障碍根容器是带aria-labelledby的fieldset标签 id 由useInstanceId生成index.tsx在多个实例并存时不会冲突。边界情形fontSizes为空且disableCustomFontSizes为true时组件渲染nullvalue为undefined时 Reset 按钮禁用但可访问accessibleWhenDisabled。七、相关源码索引内容路径组件 READMEProps 契约packages/components/src/font-size-picker/README.md主组件与状态流转packages/components/src/font-size-picker/index.tsxProps / FontSize TS 类型packages/components/src/font-size-picker/types.tsSelect 形态5 个预设packages/components/src/font-size-picker/font-size-picker-select.tsxToggleGroup 形态≤5 个预设packages/components/src/font-size-picker/font-size-picker-toggle-group.tsxhint 生成与简单 CSS 值判定packages/components/src/font-size-picker/utils.tsT 恤标签常量packages/components/src/font-size-picker/constants.tsEmotion 样式packages/components/src/font-size-picker/styles.ts浏览器测试行为契约packages/components/src/font-size-picker/test/index.browser.test.tsxStorybook 示例packages/components/src/font-size-picker/stories综上FontSizePicker 的设计可以概括为一份受控的三形态字号选择 UI——以预设数量5 为界自动切换 ToggleGroup/Select以“值是否命中预设”自动判定自定义态以“值是否为字符串”自动判定单位模式把重置语义和 slug 唯一性约束留给调用方。理解上述四条判定规则后即可在自定义块检查器中可靠地复用它。【免费下载链接】gutenbergThe Block Editor project for WordPress and beyond. Plugin is available from the official repository.项目地址: https://gitcode.com/GitHub_Trending/gu/gutenberg创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

读完文章,也想定制专属网站?

尧图设计师 24 小时内与您沟通定制方案

免费获取报价