十年匠心定制 · 商业建站与技术教学双线并行 咨询热线:400-886-1026 service@lmnt.cn
ARTICLE DETAIL

资讯详情

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

radix-vue 日历组件详解:CalendarGrid 网格容器的 Props、语义与无障碍实现

radix-vue 日历组件详解:CalendarGrid 网格容器的 Props、语义与无障碍实现 radix-vue 日历组件详解CalendarGrid 网格容器的 Props、语义与无障碍实现【免费下载链接】radix-vueAn open-source UI component library for building high-quality, accessible design systems and web apps for Vue. Previously Radix Vue项目地址: https://gitcode.com/GitHub_Trending/ra/radix-vue导读CalendarGrid是 radix-vueReka UI日历组件体系中负责承载日期网格的核心容器默认渲染为 HTMLtable并承担了日历在只读/禁用状态下的无障碍语义暴露。本文以 CalendarGrid.md 的 Props 文档为主体结合仓库源码与测试用例深入讲解as/asChild两个 Props 的用法、默认渲染元素、roleapplication与aria-*属性的实现机制并给出一个可复制运行的完整日历网格示例。读完后你将能独立定制日历网格的渲染元素并理解其状态传播与无障碍设计。CalendarGrid 在日历结构中的定位在 calendar.md 的 Anatomy结构解剖中CalendarGrid位于CalendarRoot之下与CalendarGridHead、CalendarGridBody、CalendarGridRow、CalendarHeadCell、CalendarCell等部件共同拼装出标准的日期表格script setup import { CalendarCell, CalendarCellTrigger, CalendarGrid, CalendarGridBody, CalendarGridHead, CalendarGridRow, CalendarHeadCell, CalendarHeader, CalendarHeading, CalendarNext, CalendarPrev, CalendarRoot, } from reka-ui /script template CalendarRoot CalendarHeader CalendarPrev / CalendarHeading / CalendarNext / /CalendarHeader CalendarGrid CalendarGridHead CalendarGridRow CalendarHeadCell / /CalendarGridRow /CalendarGridHead CalendarGridBody CalendarGridRow CalendarCell CalendarCellTrigger / /CalendarCell /CalendarGridRow /CalendarGridBody /CalendarGrid /CalendarRoot /template从上述结构可以看到CalendarGrid是整个日期表格的外壳负责把星期表头Head和日期单元Body组织进同一个表格容器中。它的状态禁用/只读由 CalendarRoot.vue 通过createContext建立的CalendarRootContext注入这一点在下方状态传播小节会详细展开。Props 完整参考继承自官方文档根据 CalendarGrid.mdCalendarGrid共暴露两个 PropsNameDescriptionTypeRequiredDefaultasThe element or component this component should render as. Can be overwritten by asChild.AsTag \| ComponentNotableasChildChange the default rendered element for the one passed as a child, merging their props and behavior. Read our Composition guide for more details.booleanNo-as自定义渲染元素as接受一个 HTML 标签名AsTag或一个 Vue 组件Component用于改变CalendarGrid最终渲染出的 DOM 元素。默认值为table即直接产出原生table。常见使用场景在样式框架如 Tailwind中需要给table外层再加包裹元素时将其改为div、section等块级元素与 UI 库的表格组件组合例如将as指向某个封装好的表格组件需要精确控制表格语义时保持默认table即可。CalendarGrid assection !-- 渲染为 section 而不是 table -- /CalendarGridasChild以子元素替换默认元素asChild为布尔类型没有默认值。当设置为true时CalendarGrid不再渲染自身的默认标签而是把组件内部的所有 Props 与行为合并到作为子元素传入的那个节点上。子元素可以是任意元素或组件最终只渲染这一个子元素。CalendarGrid as-child table !-- CalendarGrid 的 tabindex、role、aria-* 等属性与行为会合并到 table 上 -- /table /CalendarGridasChild与as的关系是as定义默认渲染元素而asChild可以覆盖overwriteas的决定——一旦传入子元素就以子元素为准。这也是文档描述中Can be overwritten by asChild可被asChild覆盖的确切含义。更详细的组合语义可参考仓库中的 Composition 指南docs/content/docs/guides 目录下相关文档。源码级实现默认元素与状态注入CalendarGrid的实现位于 CalendarGrid.vue核心代码非常精简全部逻辑都建立在Primitive组件之上const props withDefaults(definePropsCalendarGridProps(), { as: table }) const rootContext injectCalendarRootContext() const disabled computed(() rootContext.disabled.value ? true : undefined) const readonly computed(() rootContext.readonly.value ? true : undefined)Primitive v-bindprops tabindex-1 roleapplication :aria-readonlyreadonly :aria-disableddisabled :data-readonlyreadonly :data-disableddisabled slot / /Primitive可以提炼出三个实现要点默认值来自withDefaultsas的默认值table在源码中以withDefaults声明与文档表格完全一致状态来自 Root 上下文disabled与readonly并非CalendarGrid自身的 Props而是通过injectCalendarRootContext()从 CalendarRoot.vue 提供的上下文中读取的响应式引用并在本地用computed转换为布尔值。这意味着你只需在CalendarRoot上设置disabled/readonly整棵日历树包括网格的状态会自动联动固定携带表格无关语义属性组件无条件渲染tabindex-1与roleapplication——前者保证网格本身可被程序化聚焦但不会进入 Tab 键序后者向辅助技术声明这是一个可交互的应用程序区域。传递链从 Root 到 Grid状态传递的完整链路为用户在CalendarRoot上设置disabled/readonlyPropsCalendarRoot将其转为Refboolean后放入provideCalendarRootContext({ disabled, readonly, ... })见 CalendarRoot.vueCalendarGrid通过injectCalendarRootContext()取回并计算aria-readonly/aria-disabled。无障碍与状态语义data-* / aria-* 属性calendar.md 中为 Grid 部件列出了两张数据属性表可作为CalendarGrid状态语义的官方补充AttributeValues[data-readonly]Present when readonly[data-disabled]Present when disabled对应到源码 CalendarGrid.vuearia-readonly仅在CalendarRoot.readonly为真时输出truearia-disabled仅在CalendarRoot.disabled为真时输出truedata-readonly/data-disabled同时以data-*属性暴露供 CSS 选择器或测试定位使用。这些行为有测试用例背书。在 Calendar.test.ts 的prevents selection but allows focus when readonly is true用例中仓库明确断言了网格的只读语义const grid getByTestId(grid-1) expect(grid).toHaveAttribute(aria-readonly, true) expect(grid).toHaveAttribute(data-readonly)同时测试还验证了只读与禁用的行为差异只读模式下日期仍可聚焦firstDayOfMonth.focus()后仍持有焦点但点击不会选中而禁用模式下日期不可聚焦且aria-disabled为真见同文件 Calendar.test.ts 附近的用例。这说明CalendarGrid的语义属性不是装饰而是与整棵日历树的交互策略严格同步的。与相邻网格部件的分工CalendarGrid只负责外层容器其内部的表头、表体与行均有各自的独立组件默认渲染元素各不相同均来自对应源码的withDefaults组件默认渲染元素额外语义源码位置CalendarGridtabletabindex-1、roleapplication、aria-readonly、aria-disabledCalendarGrid.vueCalendarGridHeadtheadaria-hiddentrue对辅助技术隐藏表头CalendarGridHead.vueCalendarGridBodytbody—CalendarGridBody.vueCalendarGridRowtr—CalendarGridRow.vueCalendarHeadCellth—CalendarHeadCell.vue值得注意的设计细节CalendarGridHead默认带aria-hiddentrue因为星期几的标签信息已经通过CalendarRoot的fullCalendarLabel完整日历标签作为aria-label挂载在 Root 上并在组件内部以隐藏的roleheading元素输出提供给辅助技术表头视觉元素不再需要重复朗读。这与CalendarGrid的roleapplication共同构成了完整的 WAI-ARIA 日期网格语义。以上所有组件均继承PrimitiveProps因此as/asChild的能力同样适用于它们可实现整棵表格树的元素级定制。完整可运行示例带状态的日历网格结合前述内容下面是一个同时使用as定制与只读状态的完整示例假设已安装internationalized/date与 radix-vue并引入所需部件script setup import { CalendarCell, CalendarCellTrigger, CalendarGrid, CalendarGridBody, CalendarGridHead, CalendarGridRow, CalendarHeadCell, CalendarHeader, CalendarHeading, CalendarNext, CalendarPrev, CalendarRoot } from reka-ui import { ref } from vue // 日历是否只读由 CalendarRoot 统一控制 const readonly ref(false) /script template CalendarRoot :readonlyreadonly classcalendar CalendarHeader CalendarPrev / CalendarHeading / CalendarNext / /CalendarHeader !-- 保持默认 table但可通过 as 随时替换渲染元素 -- CalendarGrid CalendarGridHead CalendarGridRow CalendarHeadCell v-forday in 7 :keyday / /CalendarGridRow /CalendarGridHead CalendarGridBody CalendarGridRow v-forrow in 6 :keyrow CalendarCell v-forcol in 7 :keycol CalendarCellTrigger / /CalendarCell /CalendarGridRow /CalendarGridBody /CalendarGrid /CalendarRoot /template style /* 当 readonly 为真时网格会带上 contenteditable="false">【免费下载链接】radix-vueAn open-source UI component library for building high-quality, accessible design systems and web apps for Vue. Previously Radix Vue项目地址: https://gitcode.com/GitHub_Trending/ra/radix-vue创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表