尧图网站设计 尧图网站设计YAOTU DESIGN
ARTICLE DETAIL

资讯详情

深耕网站设计与一线实操的经验洞察。

astryx Stack 组件契约解析:Flex 布局原语的布局契约、Theming 所有权与验证体系

astryx Stack 组件契约解析:Flex 布局原语的布局契约、Theming 所有权与验证体系 astryx Stack 组件契约解析Flex 布局原语的布局契约、Theming 所有权与验证体系【免费下载链接】astryxAn open source design system thats fully customizable and agent ready项目地址: https://gitcode.com/GitHub_Trending/as/astryx导读本文围绕 astryx 设计系统中 Stack.spec.md 这份组件契约文档展开深入拆解 Stack / StackItem 两个布局原语的行为不变式FR1–FR4、theming 目标所有权、容器内边距协议边界以及对应的验证映射。读完本文你将理解为什么 Stack 的 padding 是本地的而不参与 container-padding 协议、stack与stack-item两个 theming target 各自覆盖哪些视觉属性以及如何通过源码、测试与知识校验脚本共同锁定这份契约。文中所有结论均可回溯到仓库内对应源码与测试文件便于直接对照验证。一、组件契约Component Contract是什么在 astryx 仓库中packages/core/src/*/下的每个组件目录都有一套成体系的知识文件.spec.md契约、.doc.mjs面向消费者的文档数据、.tsx实现、.test.tsx测试与.stylex.ts样式工具。其中.spec.md采用 YAML front-matter Markdown 的结构声明了schema_version: 3、kind: component、组件 IDcomponent:Stack以及当前状态authority: draft并登记了 ownercixzhang、审查触发器layout, theming与验证文件清单verified_by。这份契约的定位是**记录性契约**而非变更提案——它在 Intent 一节明确写道本草案只记录当前消费者解剖结构与 theming 所有权不改变任何布局、内边距、target 或公共 API。这意味着阅读该文档的正确方式是把它当作组件的事实基线current facts配合源码与测试来理解组件的稳定承诺。二、意图与所有权边界Stack 管什么不管什么2.1 组件职责Stack.spec.md 的 Intent 给出了核心定义Stack 沿单一 flex 轴排布调用方提供的内容可选的StackItem包装单个子项用于控制该子项在布局中的参与方式。从源码看这份职责被拆成两个组件实现Stack.tsx统一容器组件通过directionprop 支持horizontal等价于 HStack与vertical等价于 VStack默认值两种流向StackItem.tsx可选包装器提供sizestatic/fill、crossAlignSelf、isScrollable三个布局控制点index.ts 同时导出Stack、HStack、VStack、StackItem方便按需选用。2.2 Ownership boundary契约通过Owns / Does not own两栏划清了责任边界这对理解整个 theming 体系至关重要归属内容Owns拥有Stack 容器及其当前的stacktheming target可选的 StackItem 包装器及其stack-itemtheming targetDoes not own不拥有调用方提供给 Stack / StackItem 的内容内容所有权归调用方容器内边距的发布publish与后代溢出descendant bleed行为——Stack 的 padding 目前是本地的不参与 container-padding 协议任何新增的布局、padding 或响应式行为这个本地 padding的约定在源码中有直接对应Stack.tsx通过paddingInlineStartStyles、paddingInlineEndStyles、paddingBlockStartStyles、paddingBlockEndStyles来自 Layout/padding.stylex.ts将 padding 直接落在容器自身的 StyleX 样式上既没有对外发布几何信息也没有向后代透传——这正是契约 FR4 的源码级注脚。2.3 兼容性与迁移状态契约文档声明了三条兼容性事实Released default preservedyes兼容性类别仅追加文档additive documentation only运行时、DOM、样式、target 与公共 API 均保持不变迁移决策无无需任何迁移。因此消费方可以放心本文描述的行为就是当前发布行为不存在隐性破坏。三、行为与布局契约四条候选不变式FR1–FR4契约用一张不变式表记录了四条候选不变式candidate invariant每条都标注了依据Basis与评审状态均为已核实当前行为未决定新行为。这是全文最核心的骨架ID候选不变式依据FR1Stack、HStack、VStack 在携带当前stacktarget 的容器中渲染调用方内容当前源码、文档、测试与家族契约FR2StackItem 在携带当前stack-itemtarget 的自己的包装器中渲染调用方内容当前源码、文档与测试FR3Stack 与 StackItem 直接渲染调用方提供的内容不对其应用内容专属的公共 target当前源码与测试FR4Stack 现有的 padding 保持本地性不向后代发布 container-padding 几何信息当前源码与架构记录3.1 源码验证FR1 与 FR2 的 target 附着FR1 的携带 stack target在实现中通过themeProps(stack, …)落地。Stack.tsx 在createElement时用mergeProps合并了themeProps(stack, {direction, gap, wrap})与stylexProps最终渲染出携带astryx-stack类名见 Stack.doc.mjs 中theming.targets的className: astryx-stack的容器。FR2 同理StackItem.tsx 通过themeProps(stack-item, {size})让包装器携带astryx-stack-itemtarget。值得注意的是themeProps只携带视觉属性白名单Stack 是direction/gap/wrapStackItem 是size。换句话说只有这些属性才被登记为 theming 可视属性visualProps这与契约不改 target的承诺一致。3.2 源码验证FR3 不套内容 targetFR3 保证内容不被包一层带 target 的壳。观察 Stack.tsx 的渲染逻辑children直接作为容器的子节点传入没有被任何额外包装元素包裹StackItem.tsx 同样直接渲染children。这从 DOM 结构上保证了一个容器/包装器 裸内容的最小结构也是后续 theming 解剖中Content 不映射 target的根因。3.3 源码验证FR4 padding 本地化FR4 的边界在 Stack.tsx 中体现为 padding 的解析与落位逻辑// edge prop - axis prop - padding逐边取最具体者 const resolvedPaddingInlineStart paddingInlineStart ?? paddingInline ?? padding; const resolvedPaddingInlineEnd paddingInlineEnd ?? paddingInline ?? padding; const resolvedPaddingBlockStart paddingBlockStart ?? paddingBlock ?? padding; const resolvedPaddingBlockEnd paddingBlockEnd ?? paddingBlock ?? padding;这些解析结果全部通过stylex.props(...)作为容器自身的本地样式应用不存在向后代暴露可继承的 padding 几何。这与 container-padding.md 中记录的协议形成对照Stack 是协议外的本地 padding 组件而Card、LayoutContent、LayoutPanel等才参与发布。这一差异正是设计上允许的allowed variation——调用方内容可以直接渲染在 Stack 内也可以放进可选的 StackItem 包装器且不改变 target 所有权。3.4 允许变化与代表状态Allowed variation内容可直挂 Stack也可放入 StackItem两种路径都不改变 target 归属Representative states横向与纵向 Stack 共用同一容器 targetStackItem 在static、fill、可滚动三种行为下均使用自己的 item targetTransformation / precedence不引入任何新的方向、对齐、间距、尺寸或 padding 优先级规则Performance不引入新的性能或资源规则。四、Theming 解剖stack 与 stack-item 两个 target契约的 Theming anatomy 一节用 JSON 定义了组件解剖元素到 theming target 的映射这是组件主题化表面component-theming-surface.md在 Stack 上的具体实例{ Stack container: {target: stack}, Item: {target: stack-item}, Content: { none: { reason: intentional: Caller-supplied content retains its own theming ownership; Stack and StackItem apply no content target. } } }解读这份解剖图Stack container →stack容器是唯一持有stacktarget 的元素Item →stack-item可选的 StackItem 包装器持有stack-itemtargetContent → 无 target这是有意的设计决策。调用方内容保留自己的 theming 所有权Stack / StackItem 绝不替内容做样式决策。这也直接支撑了 FR3。在文档数据层面Stack.doc.mjs 的theming.targets给出了两份类名与可视属性清单classNamevisualPropsastryx-stackdirection、gap、wrapastryx-stack-itemsize配合 stack.stylex.ts 可见这些 visualProps 的取值来源direction映射flexDirectionrow/columngap映射主题间距 token--spacing-0至--spacing-10支持0, 0.5, 1, 1.5, 2, 3, 4, 5, 6, 8, 10共 11 档wrap映射flexWrapnowrap/wrap/wrap-reverse。主题制作者可以只针对这些属性做差异化定制而不会触碰未登记的布局细节。五、设计关系与家族归属契约的 Design relationships 表把解剖元素与设计需求、代表权威、层级角色、组件契约做了关联解剖或状态设计需求代表权威层级角色组件契约Stack 容器呈现一维布局容器当前源码、文档与家族契约SupportingFR1、FR4Item可选地控制一个子项在 Stack 中的参与当前源码、文档与家族契约SupportingFR2Content在两个公共包装器中呈现调用方内容调用方提供的内容Context-dependentFR1、FR2、FR3在家族与系统层面契约明确登记了三层关系family:layout-primitiveslayout-primitives.md拥有 Stack 的方向、对齐、间距、尺寸、padding 与子项参与方式item-participation的共享词汇。也就是说Stack 的 prop 语义不是孤立的而是家族级布局词汇的具体载体architecture:container-paddingcontainer-padding.md记录了Stack padding 是本地且不发布后代溢出几何这一事实architecture:component-theming-surfacecomponent-theming-surface.md拥有解剖资格认定与 target 映射规则Stack 的 theaming anatomy JSON 即按此规则书写。此外契约明确不引入任何新的公共概念No new public concept消费者 props 与用法继续由Stack.doc.mjs文档化家族layout-primitives拥有共享布局词汇。这与契约纯记录、零变更的基调完全一致。六、验证映射契约如何被仓库锁定一份契约如果没有验证手段就是空文。Stack 契约的 Verification map 把每条不变式映射到具体的验证资产与破坏预期契约验证代表状态变更/失败预期审计段FR1、FR3、FR4Stack.test.tsx 渲染、props 与 padding 套件横/纵、直接内容、padding移除容器/内容或修改内置本地 padding 会破坏既有测试audit:Stack/anatomyFR2、FR3StackItem.test.tsx 渲染与行为套件static、fill、多态、可滚动移除包装器/内容或改变当前 item 行为会破坏既有测试audit:StackItem/anatomyTarget 清单themingTargets.test.tsStack 与 StackItem 的 target运行时与文档化的 target 元数据漂移会触发 target 校验失败audit:Stack/themingTheming 解剖图check-knowledge.mjs规范解剖与两个当前 target缺失、多余、带前缀或过期的映射会触发仓库级校验失败audit:Stack/theming6.1 源码测试如何兑现 FR1–FR3Stack.test.tsx 覆盖了契约最关心的行为面方向与容器默认vertical、显式horizontal/vertical均能渲染默认渲染为DIV多态渲染asnav、assection时 tagName 分别为NAV、SECTIONFR1 的容器不绑定具体元素内容直渲children 直接可见FR3 无内容包裹对齐别名justify/align别名在横、纵方向都能解析且显式hAlign优先于别名尺寸语义数字width{300}输出300px字符串width100%原样输出Stack.tsx 的 SizeValue 处理逻辑padding 优先级paddingBlockStart/paddingBlockEnd只覆盖自身边缘、paddingBlockEnd优先于paddingBlock、四边独立解析——测试里甚至用四种显式边值与shorthand 覆盖两种写法做类名集合等价断言精确锁定了 FR4 的本地 padding 解析规则。StackItem.test.tsx 则锁定 FR2 / FR3默认DIV、多态section、sizefill/sizestatic、crossAlignSelf、ref 转发、额外 props 透传以及isScrollable类名切换与sizefill isScrollable组合。6.2 theaming 解剖如何被机器校验契约的verified_by字段列出的 themingTargets.test.ts 与 check-knowledge.mjs 属于元数据层面的双保险前者校验运行时/文档化的 target 清单没有漂移后者以仓库级校验对应audit:Stack/theming检查规范解剖映射中是否存在缺失、多余、错误前缀或过期条目。也就是说Stack 容器 → stack、Item → stack-item、Content → none这条解剖事实不仅写在文档里还被自动化校验强制保持与源码和文档数据同步。七、决策日志与内容边界契约的最后三节看似琐碎实则是知识治理的关键Decision logNone——本草案仅记录当前事实未引入任何组件局部的设计、布局或 API 决策。这再次印证其记录型契约属性Open questionsNone——当前不存在悬而未决的问题Content boundary——本文件不重复消费端 prop 表格、示例、家族布局规则、container-padding 机制、实现步骤或系统规则而是通过链接指向这些内容的所有者。这正是 astryx 知识分层knowledge contract的设计.spec.md管契约.doc.mjs管消费者文档家族/架构文档管共享词汇。八、实战速查Stack / StackItem 的关键参数与用法为了让契约与实际开发衔接这里基于 Stack.doc.mjs 与源码整理出可直接使用的参数速查以下用法与当前仓库实现一致// 统一组件direction 决定流向默认 vertical Stack directionvertical gap{2} Item / Item / /Stack // 水平堆叠 主轴两端对齐 交叉轴居中 Stack directionhorizontal gap{4} vAligncenter hAlignbetween Item / Item / /Stack // 用 StackItem 让中间子项填满剩余空间 HStack gap{2} StackItem sizestaticLogo/StackItem StackItem sizefillContent/StackItem StackItem sizestaticActions/StackItem /HStack // 完整滚动区域StackItem 自带 min-size reset StackItem sizefill isScrollable LongContent / /StackItem关键参数约定directionhorizontal | vertical默认vertical。注意取值是horizontal不是rowgap / padding 系列数字字面量步进0 | 0.5 | 1 | 1.5 | 2 | 3 | 4 | 5 | 6 | 8 | 10必须以 JSX 数字表达式传入gap{4}而非gap4底层映射主题间距 tokenhAlign / vAlign根据 direction 自动映射到justify-content或align-items。主轴取值start | center | end | between | around | evenly对应between而非space-between交叉轴取值start | center | end | stretchjustify / align分别对应 CSSjustify-content/align-items的语义别名显式hAlign/vAlign优先padding 优先级edge prop axis prop padding逐边解析、互不污染FR4 的消费端视角尺寸width/height/maxWidth/minHeight数字按像素、字符串原样如100%、50vhStackItem.sizestatic保持固有尺寸、不缩放默认或fillflexGrow: 1填充剩余空间crossAlignSelf覆盖父级交叉轴对齐isScrollable提供overflow: auto并自带 flexmin-width/min-height重置见 stackItem.stylex.ts 的minSizeResetStyles。最佳实践来自Stack.doc.mjs的 usage 部分用gap控制子项间距、不要手动加 margin需要让某项占满剩余空间时用StackItem sizefill避免无脑嵌套 Stack先尝试wrapwrap让内容自然换行。结语Stack 契约看似是一份什么都没改的记录文档但它恰恰体现了设计系统最需要的东西稳定的行为基线。FR1–FR4 四条不变式把容器 target、item target、内容免样式包裹、padding 本地化这四个关键承诺钉死theming 解剖图明确了stack/stack-item的目标归属与Content的有意无 target设计验证映射则把每一句承诺都接入了测试与仓库级校验。对组件消费者而言这份契约意味着 Stack 的行为可以被信任、被引用、被测试对主题制作者而言它划清了可定制边界方向/间距/换行/尺寸与不可触碰的布局底线。理解 Stack 契约也就理解了 astryx 知识体系中组件契约如何与源码、文档、测试三线对齐的完整范式。【免费下载链接】astryxAn open source design system thats fully customizable and agent ready项目地址: https://gitcode.com/GitHub_Trending/as/astryx创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表