ARTICLE · INTELLIGENCE

战地情报 · 详情页

来自尧图项目组的一线实战观察与深度解析

Carbon React preview__DatePicker 迁移指南:从 Flatpickr 时代走向 Temporal + 状态机架构

Carbon React preview__DatePicker 迁移指南:从 Flatpickr 时代走向 Temporal + 状态机架构 Carbon React preview__DatePicker 迁移指南从 Flatpickr 时代走向 Temporal 状态机架构【免费下载链接】carbonA design system built by IBM项目地址: https://gitcode.com/GitHub_Trending/carbo/carbonpreview__DatePicker是carbon/react中新一代DatePicker的预览实现它基于Temporal API与一套框架无关的状态机与carbon/web-components共享核心逻辑位于carbon/utilities/date-picker用以取代基于 Flatpickr 的经典实现。由于新的 prop 表面与经典 v11 组件高度一致绝大多数迁移只需要改一行 import。本文将以官方迁移指南为主线结合仓库源码为你梳理需要检查的全部行为差异、浏览器兼容性前提与迁移检查清单帮助你在不破坏现有表单逻辑的前提下平滑升级。注意该组件目前处于preview预览阶段API 与行为在正式 GA 前仍可能变化部分经典功能尚未实现生产环境接入前请务必评估。一、为什么要迁移从 Flatpickr 到「Temporal 状态机」经典版DatePicker由 Flatpickr 驱动而preview__DatePicker彻底换掉了底层引擎。新架构的核心是位于 packages/utilities/src/date-picker 的框架无关状态机其设计原则见 primitives/README.md包括零依赖仅使用 TypeScript 标准库框架无关核心逻辑为纯 TypeScript可移植到 React / Angular / Vue / Web Components不可变更新所有状态变更返回新的 context 对象类型安全严格模式下的完整 TypeScript 覆盖可测试不依赖 DOM易于单元测试。状态机定义了IDLE、FOCUSED、CALENDAR_OPEN、SELECTING_START、SELECTING_END、DATE_SELECTED、DISABLED、READONLY、ERROR等状态并通过INPUT_FOCUS/INPUT_BLUR、CALENDAR_OPEN/CALENDAR_CLOSE、DATE_SELECT、RANGE_START_SELECT/RANGE_END_SELECT、NEXT_MONTH/PREV_MONTH、OUTSIDE_CLICK、ESCAPE_KEY/TAB_KEY/ENTER_KEY、DISABLE/ENABLE、SET_READONLY/UNSET_READONLY等事件驱动迁移。范围选择逻辑如结束日期早于开始日期时自动交换也由状态机内建处理。在 React 侧DatePicker.tsx 组件通过 useDatePicker.ts 这个 hook 实例化DatePickerStateMachine并将状态机上下文context、send事件派发方法、输入框 ref、日历容器 ref 等统一暴露给组件渲染层——这解释了为什么组件源码注释中反复强调Maintains 100% backwards compatibility with Carbon React v11 API。二、浏览器支持与 Temporal Polyfill无需你做任何事Temporal 目前并未在所有浏览器中普遍可用没有任何版本的 Safari 实现它Chrome/Edge 要到 144 版本才原生支持。为此carbon/utilities/date-picker的入口 index.ts 在导出 primitives 之前首先执行import temporal-polyfill/global;该模块只在引擎没有原生Temporal实现时才把globalThis.Temporal安装到全局如果引擎已提供原生实现则永远以原生实现优先a native implementation always wins。也就是说polyfill 的引入与装载完全由库内部处理你不需要引入第二个 Temporal polyfill否则可能造成实现冲突必须通过carbon/utilities/date-picker这个入口访问 primitives——直接导入某个 primitive 模块会跳过 polyfill 安装导致Temporal.*访问抛ReferenceError。这一行为有专门的回归测试保障见 temporal-polyfill-test.js该测试故意不引入temporal-mock而是全部经由入口../../index.js导入断言导入后isTemporalAvailable()为true、Temporal.Now.plainDateISO可调用并验证在无原生 Temporal 环境下日历仍能正常打开、网格渲染与月份导航不抛错。三、导入路径只改 import不改 JSX从carbon/react导入preview__DatePicker命名空间后解构出组件JSX 保持不变- import { DatePicker, DatePickerInput } from carbon/react; import { preview__DatePicker } from carbon/react; const { DatePicker, DatePickerInput, DatePickerSkeleton } preview__DatePicker;命名空间的导出定义在 next/index.tsx它同时导出了DatePicker、DatePickerInput、DatePickerSkeleton以及对应的 Props 类型DatePickerProps、DatePickerInputProps、DatePickerSkeletonProps。解构之后用法与 v11 组件完全一致DatePicker datePickerTypesingle onChange{handleChange} DatePickerInput iddate labelTextDate placeholdermm/dd/yyyy / /DatePicker四、行为差异三处必须检查的破坏性变更虽然 prop 表面保持不变但以下三处回调签名与底层能力发生了破坏性变化是迁移时最容易踩坑的地方1.onChange签名(selectedDates, dateStr, instance)→(dates: Date[])经典实现调用onChange(selectedDates, dateStr, instance)而preview__DatePicker只传入一个Date对象数组- const handleChange (selectedDates, dateStr, instance) setValue(dateStr); const handleChange (dates) { const [start, end] dates; // format yourself, e.g. Intl.DateTimeFormat };这与 DatePicker.tsx 中onChange?: (dates: Date[]) void的类型声明一致。在 hook 实现useDatePicker.ts中可以看到具体机制状态机的 context 里存的是Temporal.PlainDatestartDate/endDateReact 侧通过plainDateToDate把PlainDate转回普通Date后拼成数组并以 ISO 字符串拼接为 key 做去重只有日期真正变化时才触发onChange。2.onClose签名(selectedDates, dateStr, instance)→onClose()经典实现传入三个参数新实现无参调用。因此关闭回调里不要再依赖参数读取选中日期而是直接读取你自己维护的 state。在 hook 中onClose是通过订阅状态机转换、检测isOpen由true变为false时触发的useDatePicker.ts。3. 没有 Flatpickr API新实现不再由 Flatpickr 驱动因此任何 Flatpickr 专属的 API、插件、选项都不会被透传或生效。如果你在经典组件上依赖了 Flatpickr 的appendTo、plugins见 plugins 目录中的appendToPlugin、rangePlugin、fixEventsPlugin等能力迁移前需要为它们寻找替代方案。其余 props 与经典组件保持一致除上述差异外其余 props 均与经典组件匹配关键格式约定为minDate/maxDate使用mm/dd/yyyy格式字符串组件内会通过parseDateToPlainDate统一解析为Temporal.PlainDate后交给状态机做范围约束与守卫校验locale接受BCP 47 语言标签如en、zh-CN用于控制月份与星期文本的本地化默认值en见组件解构默认参数。组件完整支持的 props 及其默认值来自 DatePicker.tsx汇总如下Prop类型默认值说明datePickerTypesimple \| single \| rangesingle选择器类型simple不渲染日历下拉dateFormatstringm/d/Y兼容 Flatpickr 的日期格式串minDate/maxDatestringundefined最小/最大可选日期mm/dd/yyyy范围外日期自动禁用localestringenBCP 47 标签控制月份/星期文案readOnlybooleanfalse只读light/shortbooleanfalse浅色 / 紧凑变体allowInputbooleantrue允许手动输入closeOnSelectbooleantrue选中日期后是否自动关闭日历onChange(dates: Date[]) void—选中变化回调见上方签名差异onClose/onOpen() void—关闭 / 打开回调onClose无参classNamestring—附加类名valuestring—初始值ISO 日期字符串五、迁移检查清单逐项核对以下内容即可完成从经典DatePicker到preview__DatePicker的迁移从preview__DatePicker命名空间导入组件并解构确认已适配新的行为差异onChange只收到Date[]不再有dateStr与instance格式化请自行处理如Intl.DateTimeFormatonClose无参数从自身 state 读取当前值若使用了 Flatpickr 专属 API 或插件如appendTo、plugins已找到替代方案无任何对 FlatPickr API 的依赖残留六、反馈与预览期注意事项该组件仍处于 preview 阶段你的反馈将直接影响其正式发布形态。若遇到 bug、非预期行为或任何相关建议官方文档指引通过 GitHub Issues 提交反馈或通过 Slack 联系维护团队。最后再次强调预览期风险API 与行为在正式 GA 前可能变化且部分经典功能尚未实现。建议在迁移到生产环境前先基于现有组件测试用例如 DatePicker-test.js与状态机测试primitives/tests验证你的表单交互路径再逐步灰度替换经典组件。【免费下载链接】carbonA design system built by IBM项目地址: https://gitcode.com/GitHub_Trending/carbo/carbon创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
RELATED READING

延伸阅读

更多一线实战笔记与深度复盘,助您持续精进