news 2026/9/15 20:33:57

Astryx 布局原语家族契约:Stack、Grid、Center 与共享空间词汇表

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
Astryx 布局原语家族契约:Stack、Grid、Center 与共享空间词汇表

Astryx 布局原语家族契约:Stack、Grid、Center 与共享空间词汇表

【免费下载链接】astryxAn open source design system that's fully customizable and agent ready项目地址: https://gitcode.com/GitHub_Trending/as/astryx

导读

布局原语(layout primitives)是任何设计系统里最高频、最容易被各业务团队各自为政的部分。Astryx 通过一份 family contract 文档(docs/families/layout-primitives.md)将 Stack、HStack、VStack、StackItem、Grid、GridSpan、Center 七个成员收敛为"同一个小词汇表":选择 Stack、Grid 或 Center 只改变排列模型,而间距刻度、尺寸语义、对齐方向、padding 优先级这些共享概念在家族内保持唯一含义。本文以这份契约为骨架,结合 packages/core/src 下的真实实现与测试,讲解每个成员的能力边界、共享不变量(FR1–FR9)、允许的组件差异(AV1–AV7),以及一份可直接落地的实战组合方案,帮助你写出风格一致、可维护、可主题化的布局代码。

家族契约的意图:排列模型不同,词汇表唯一

契约开宗明义地定义了自己的 Intent:开发者应该能用同一种小词汇表来排列任意内容(一维或二维)、居中它、设置布局盒尺寸、表达空间关系。选择 Stack、Grid 还是 Center 改变的是"排列模型"(arrangement model),而不是引入第二套间距刻度或给共享 prop 名赋予新含义。

这一原则落实到组件层面,意味着:

  • gappaddingwidthheight在七个成员间遵循同一套数值语义(SpacingStep/SizeValue);
  • 轴的语义(main/cross axis)由当前成员的排列模型解析,而不是各组件自行发明;
  • "间距刻度"永远只有一套,来自主题 token,而不是每个组件复制一份魔法数字。

从源码看,这一意图被严格执行:Stack 的 gap 样式、Grid 的 gap/rowGap/columnGap 样式都指向同一个spacingVarstoken 表(见 stack.stylex.ts 与 Grid.tsx),数值经过SpacingStep类型约束后映射到--spacing-*变量,而非各写各的像素值。

成员规则与边界:什么算布局原语

成员规则(Membership rule)

契约用"公共职责"(primary public purpose)而非"实现机制"来判定归属:

一个组件属于该家族,当且仅当它的主要公共用途是通过共享的布局原语词汇表排列任意子内容;一个修饰器(modifier)归属于其父组件,当它改变某个子元素在该排列中的参与方式。

成员(Members):

成员职责
Stack一维排列:方向、换行、主轴/交叉轴对齐
HStack / VStackStack 契约的固定方向形式
StackItem修改 Stack 中单个子元素的参与方式
Grid二维轨道排列:固定列与固有/流式列
GridSpan修改 Grid 中单个子元素的行、列跨距
Center沿单轴或双轴居中

协作者(Collaborators):共享的SpacingStepSizeValue类型;Stack 与 StackItem 的样式工具函数;padding.stylex.ts;container-padding 架构(docs/architecture/container-padding.md);组件的.doc.mjs主题元数据与运行时themeProps()发射。

明确排除(Excluded):Section、Layout 及其命名区域、Toolbar 拥有的是"结构区域"契约而非本家族的任意子内容排列词汇。Layout 虽是一般用途原语,但其公共模型是五个命名槽位而非不受限的子元素排列;FormLayout 负责字段排列与表单级可选性;AspectRatio 约束单个子元素的盒子而非排列任意子元素;Card 与 Dialog 是表面(surface);AppShell 拥有页面外壳与应用导航组合。

关键判据:一个组件不会仅仅因为源码里用了 flexbox 或 grid 就加入家族。成员资格跟随公共责任,不跟随实现机制。

共享负责人(Shared owner)

契约为每个共享概念指定了唯一负责人,避免多个组件各自解释同一概念:

概念负责人
数字间距词汇表(gap/padding 的取值)SpacingStep类型
盒子尺寸契约(数字=像素,字符串=CSS 值)SizeValue类型
一维方向、换行、主轴/交叉轴对齐Stack(HStack/VStack 为固定方向形式)
固定列与固有/流式轨道构造Grid;GridSpan 负责单个子元素的行列参与
单轴或双轴居中Center
bleed 几何(container inset 协议)architecture:container-padding(本地应用 padding 本身不发布该协议)

核心概念表:七个成员的公共语义

概念取值/状态默认语义稳定性
spacing step00.511.523456810受 token 支持的间距值,用于 gap/paddingcurrent
box size数字或 CSS 值字符串数字按像素处理;字符串原样透传为 CSS 值current
flow directionhorizontal / verticalStack 默认 vertical;HStack/VStack 固定方向current
alignmentmain/cross axis,或物理横/纵别名由当前排列模型解析轴current
gap支持处为 uniform、row、column排列项之间的间距,不是容器内边距current
padding支持处为 uniform、axis、logical edge成员自身盒子内部的空间current
item participationintrinsic、fill、self-aligned、column span、row span修饰器改变单个子元素在父排列中的角色current
responsivenessintrinsic、wrapping、consumer-authored各成员自文档化自己的可用机制component-owned

SpacingStep 的像素映射(见 utils/types.ts):0=0px0.5=2px1=4px1.5=6px2=8px3=12px4=16px5=20px6=24px8=32px10=40px,分别对应--spacing-0--spacing-10主题 token。这就是"只有一个间距刻度"的落地形式:无论你在 Stack 还是 Grid 上写gap={4},得到的都是同一个 16px 的 token 值。

SizeValue 契约type SizeValue = number | string。数字渲染为像素(${width}px),字符串原样透传(如'100%''50vh')。Stack 的width/height/maxWidth/minHeight与 Grid、Center 的同名尺寸 prop 全部遵循此契约(见 Stack.tsx 的 sizingStyle 构造)。

跨组件不变量 FR1–FR9:共享语义的硬约束

契约定义了九条跨组件不变量,它们是"共享词汇表"的执法依据:

  • FR1 — 共享名字保持共享值语义。任何被类型化为SpacingStepSizeValue的成员 prop 都遵循共享的值与强转契约;成员只暴露其排列模型支持的能力。例如 Stack 暴露 gap(一维 spacing),Grid 暴露 gap/rowGap/columnGap(二维 spacing),但都不会突然改变这些 prop 的含义。
  • FR2 — 逻辑间距跟随书写方向。inline-start/end 是逻辑边缘,成员不得将其重新解释为固定的 left/right。Center 与 Stack 的 padding 阶梯使用paddingInlineStart/EndpaddingBlockStart/End逻辑属性(见 padding.stylex.ts),RTL 下自动镜像。
  • FR3 — padding 优先级按边计算。在拥有完整 padding 阶梯的成员上,显式的边缘值 > 该轴的值 > uniformpadding;覆盖只改变该边。Stack 与 Center 的解析顺序都是edge ?? axis ?? padding(Stack.tsx、Center.tsx)。
  • FR4 — gap 与 padding 保持分离。gap 分隔排列项,padding 内缩容器内内容。Grid 的rowGap/columnGap只覆盖其所在轴的 uniform gap。
  • FR5 — 对齐跟随排列模型。Stack 依据方向解析 main/cross 轴;Grid 在轨道中对齐项目;Center 控制哪个轴(或双轴)被居中。当含义不同时,一个成员不得复制另一个成员的 prop。例如 HStack 的hAlign是主轴(justify-content),而 Stack 的hAlign在 vertical 方向下是交叉轴(align-items)——这正是契约要求"含义必须由排列模型解析"的原因。
  • FR6 — 修饰器组件要求其父模型。StackItem 控制 Stack 中的参与;GridSpan 控制 Grid 中的参与。它们各自的组件契约定义了父模型之外的行为。
  • FR7 — 响应式行为是显式的。Grid 可能因固有轨道数学而回流;Stack 仅在配置wrap时换行;Center 不创建断点。家族不承诺共享断点或自动区域切换。
  • FR8 — 本地 padding 不是 bleed 信号。Stack 与 Center 当前应用 padding 时不发布容器 inset 几何。后代组件只有在architecture:container-padding命名的发布者下才能依赖 bleed 补偿。
  • FR9 — 公共契约不规定源码结构。组件可以使用成员工具函数,也可以直接用平台布局,只要可观察的 API 与行为保持正确。

成员逐个深入:从 props 到 StyleX 实现

Stack:一维排列的唯一入口

Stack.tsx 是一个统一的一维排列组件,用direction取代了以往 HStack/VStack 各自为政的实现,默认direction="vertical"。核心 props:

<Stack direction="vertical" // 'horizontal' | 'vertical',默认 'vertical' gap={2} // SpacingStep,0–10 hAlign="center" // 主轴对齐(horizontal 下 justify-content) vAlign="stretch" // 交叉轴对齐(horizontal 下 align-items) justify="between" // 主轴别名,镜像 CSS justify-content align="center" // 交叉轴别名,镜像 CSS align-items wrap="wrap" // 'nowrap' | 'wrap' | 'wrap-reverse' padding={4} // SpacingStep paddingInline={3} // 覆盖 padding 的 inline 轴 paddingInlineStart={2} // 覆盖 inline 起始边(逻辑边) width={320} // SizeValue:数字=px height="100%" // SizeValue:字符串原样透传 isScrollable // overflow: auto as="ul" // 多态渲染 > <li>Item</li> </Stack>

关键实现细节:

  • 对齐映射hAlign/vAlign依据direction自动解析到justify-content(主轴)或align-items(交叉轴)。主轴取值'start' | 'center' | 'end' | 'between' | 'around' | 'evenly',交叉轴取值'start' | 'center' | 'end' | 'stretch'(见 stack.stylex.ts)。
  • justify/align 别名justify镜像 CSSjustify-contentalign镜像align-items,与 Tailwind 的justify-*/items-*语义对齐,降低迁移心智负担。
  • 尺寸:数字→px、字符串→透传,全部走 inline style。
  • 运行时主题发射:组件调用themeProps('stack', {direction, gap, wrap}),将视觉 prop 反射为data-*属性与稳定类名(见 themeProps.ts 的 kebab-case 转换:directiondata-direction)。

底层样式由stack()工具函数生成(stack.stylex.ts),它接受{direction, crossAlign, mainAlign, gap, wrap}返回 StyleX 样式数组,这也是"实现机制可替换(FR9)"的体现——其他组件可以直接调用stack()而不经过 Stack 组件本身。

HStack / VStack:固定方向的便捷形式

HStack 是 Stack 的极薄包装(HStack.tsx):

export function HStack({ref, justify, align, hAlign, vAlign, ...props}: HStackProps) { return <Stack {...props} direction="horizontal" {.../* 别名映射 */} />; }

HStackProps通过Omit<StackProps, 'direction' | 'hAlign' | 'vAlign'>收窄了类型:hAlign收敛为StackMainAlignment(主轴,justify-content),vAlign收敛为StackCrossAlignment(交叉轴,align-items),从类型层面保证固定方向下的合法取值。VStack 同理固定为direction="vertical"

使用建议:如果方向是"永不改变的布局事实",用 HStack/VStack 让意图自文档化并享受更窄的类型;如果方向可能随响应式策略切换,直接用Stack direction={...}

StackItem:单个子元素的参与控制

StackItem.tsx 是 Stack 的修饰器,提供两个能力:

<Stack direction="vertical" gap={2}> <StackItem size="static">Logo</StackItem> {/* flexGrow:0, flexShrink:0,固有尺寸 */} <StackItem size="fill">Content</StackItem> {/* flexGrow:1,吃掉剩余空间 */} <StackItem size="fill" isScrollable>Scroll region</StackItem> <StackItem crossAlignSelf="center">Me</StackItem> {/* align-self 覆盖 */} </Stack>

底层(stackItem.stylex.ts)有两个值得注意的设计:

  1. flex min 尺寸重置minHeight: 0; minWidth: 0总是被应用。flex 子项隐式min-size: auto,内容多时永不收缩,这个重置让子项可以被 flex 父容器约束并变得可滚动。
  2. size="fill"+isScrollable构成完整滚动区域:fill 提供flexGrow: 1,isScrollable 提供overflow: auto,加上 min 尺寸重置,一个<StackItem size="fill" isScrollable>就能生长填满 Stack 并滚动自身溢出,无需额外样式管道。Stack 的isScrollable文档也明确建议:当 Stack 本身作为 flex 子项需要滚动时,外层配StackItem size="fill" isScrollable(Stack.tsx)。

Grid:固定列与固有/流式轨道

Grid.tsx 提供 CSS Grid 布局,columnsprop 有两种形态:

// 固定等宽列 <Grid columns={3} gap={4}> <div>A</div><div>B</div><div>C</div> </Grid> // 固有/流式列:基于最小子宽度的响应式 <Grid columns={{minWidth: 280}}> {/* auto-fill,宽度一致 */} <Grid columns={{minWidth: 280, repeat: 'fit'}}> {/* auto-fit,折叠空轨 */} <Grid columns={{minWidth: 280, max: 4}}> {/* 上限 4 列,仍有 1fr 弹性 */} // 轴级 gap 覆盖 <Grid columns={3} gap={2} rowGap={3} columnGap={4} /> // 对齐(默认 stretch) <Grid columns={3} align="center" justify="start" /> // 瀑布流式行高 + GridSpan <Grid columns={3} rowHeight={80} gap={3}> <GridSpan rows={4}>Tall</GridSpan> <GridSpan rows={2}>Short</GridSpan> </Grid>

值得展开的实现细节:

  • max上限列数的数学buildCappedTemplate(Grid.tsx)把上限放在轨道的min尺寸上:每轨至少(100% - (max-1)*gap) / max,因此永远不会超过max列;而轨道 max 保持1fr,所以当实际列数少于上限时(尤其移动端单列),现有列仍会拉伸填满整行——右侧不留死区。轨道 min 是max(minWidth, perColumn)再包一层min(100%, …),保证窄视口下单列收缩到容器而不溢出。
  • 动态轨道走 CSS 变量而非 inline stylegrid-template-columns: var(--x)通过 StyleX 动态样式生成(Grid.tsx),这样消费方xstyle覆盖——包括@media内的覆盖——仍能生效;原始 inlinegrid-template-columns会压过任何类。
  • gap 三件套gap同时写 row+column,rowGap/columnGap只覆盖对应轴,且全部映射 spacing token。

GridSpan:行列跨距修饰器

GridSpan.tsx 是 Grid 的修饰器:

<Grid columns={3} gap={4}> <GridSpan columns={2}>Wide</GridSpan> {/* grid-column: span 2 */} <div>Normal</div> <GridSpan columns="full">Full row</GridSpan> {/* grid-column: 1 / -1 */} <GridSpan rows={2}>Tall</GridSpan> {/* grid-row: span 2 */} </Grid>

它的基样式自带minWidth: 0(防溢出)、display: gridheight: 100%,让内容填满所跨的格子。themeProps('grid-span')只发射稳定类名,不携带视觉数据。

Center:单轴或双轴居中

Center.tsx 用 flex 实现居中,axisprop 控制居中范围:

<Center width={300} height={200}> {/* 双轴居中 */} <Content /> </Center> <Center axis="horizontal">…</Center> {/* 仅主轴/inline 轴 */} <Center axis="vertical">…</Center> {/* 仅交叉轴/block 轴 */} <Center isInline>💬 文本/图标行内居中</Center> {/* inline-flex */} <Center padding={4}>…</Center> {/* 与 Stack 相同的 padding 阶梯 */}

实现要点:

  • both同时应用alignItems: centerjustifyContent: centerhorizontal只应用 justify-content;vertical只应用 align-items(Center.tsx)。
  • 契约代表矩阵中明确提示:居中可观察的前提是轴上存在可用尺寸<Center>不设置尺寸时,其盒子由内容撑开,居中效果不可见;需要配合width/height/maxWidth或父容器的约束。
  • 尺寸 prop(width/height/maxWidth/minHeight)通过动态样式一次函数化生成(dynamicStyles.sizing),padding 阶梯与 Stack 完全一致(edge ?? axis ?? padding)。

允许的组件差异 AV1–AV7:统一中的多样性

契约在共享语义之上,明确允许成员保留自己的特征,防止"统一"演变成"趋同":

编号差异维度内容
AV1排列模型Stack 一维流、Grid 二维轨道、Center 单/双轴对齐
AV2可用 propsStack/HStack/VStack/Center 暴露完整逻辑边 padding 阶梯;Grid 暴露轴级 gap;修饰器暴露父专属参与方式而非盒级布局控制
AV3元素所有权Stack/HStack/VStack/StackItem 多态(asprop);Grid/GridSpan/Center 当前拥有固定 div 元素
AV4溢出Stack/HStack/VStack/StackItem 暴露各自当前滚动行为(isScrollable);Grid 与 Center 不因家族成员身份获得该能力
AV5响应式Grid 固有列、Stack 换行、消费方自写响应式样式保持组件专属
AV6实现允许裸 flex/grid 与共享工具函数并存,家族成员身份不制造实现级迁移债
AV7主题化各组件的.doc.mjs元数据文档化已发布的 targets 与能力,运行时themeProps()发射它们;跨组件规则由architecture:component-theming-surface拥有

关于 AV3 有一个易混淆点:Stack 与 StackItem 的多态能力来自asprop(默认'div'),例如<Stack as="ul">渲染为列表;而 Grid/GridSpan/Center 当前固定渲染div

代表矩阵:成员状态 × 共享不变量 × 刻意差异

成员与状态共享不变量刻意差异
Stack / vertical 或 horizontal共享 spacing 与 sizing 值;方向解析对齐轴可换行、可滚动、可渲染指定元素
HStack 或 VStack同一 Stack 契约 + 固定方向更窄的对齐类型匹配固定轴
StackItem /size="fill"单个子元素可消耗 Stack 剩余空间isScrollable与 StackItem 的 flex min 重置配对
Grid / 固定列共享 size 与 gap 值显式等宽轨道数
Grid / 固有列共享 size 与 gap 值minWidth、可选列数上限、fill/fit 构造流式轨道
GridSpan / columns 或 rows修饰器参与 Grid跨轨道而非控制父几何
Center / 单轴或双轴共享 size 与 padding 值某轴居中可观察前需要可用尺寸

实战组合:把七个成员拼成一致布局

以下是一个体现"同一个小词汇表"的页面骨架示例:

import {Stack, HStack, VStack, StackItem, Grid, GridSpan, Center} from '@astryxdesign/core'; export function Dashboard() { return ( <VStack gap={5}> {/* 顶部栏:固定尺寸 Logo + 弹性内容 + 固定操作区 */} <HStack gap={3} vAlign="center" padding={4} isScrollable> <StackItem size="static"><Logo /></StackItem> <StackItem size="fill"><SearchBar /></StackItem> <StackItem size="static"><Avatar /></StackItem> </HStack> {/* 主区域:响应式网格,最大 4 列,移动端单列拉伸全宽 */} <Grid columns={{minWidth: 280, max: 4}} gap={4}> <GridSpan columns={2}><SummaryCard /></GridSpan> <GridSpan columns="full"><TrendChart /></GridSpan> <StatCard /><StatCard /><StatCard /> </Grid> {/* 底部空态:双轴居中并让内容垂直充满 */} <Center height={240} padding={6}> <VStack gap={2} hAlign="center"> <EmptyStateIcon /> <p>No data yet</p> </VStack> </Center> </VStack> ); }

这个例子覆盖了全部七个成员,且每处 spacing 都来自同一张SpacingStep表:顶部栏gap={3}是 12px,主网格gap={4}是 16px,外层gap={5}是 20px——数值即 token,无需换算。

采用情况、已知缺口与变更耦合

采用与例外

组件/关注点采用情况当前缺口或例外
Stack, HStack, VStack共享一维契约gap token 映射与 Grid 的映射分开实现
StackItem共享修饰器契约家族级 flex-item grow/shrink/basis 词汇表不存在
Grid, GridSpan共享二维契约没有跨组件测试证明 Grid 与 Stack 对相同 gap step 解析出相等的值
Center共享 sizing 与 padding 词汇与 Stack 相同,padding 是局部的、不发布 bleed 几何
共享验证各组件单元覆盖没有 computed-style 矩阵证明每个共享 spacing/sizing 值跨成员一致

契约明确声明:这些是已发布的覆盖或采用缺口,而不是授权在文档 PR 中加 props 或改布局行为的许可

变更耦合(Change coupling)

契约规定了变更必须联动审查的边界,这直接指导贡献者:

  • 增加或修改共享空间 prop,需检查其名称、值类型、强转、逻辑方向、优先级是否仍与本家族一致;
  • 修改SpacingStepSizeValue,需审查所有暴露该类型的成员,并更新代表性的跨组件证据;
  • 修改 Stack 的方向/对齐,HStack 与 VStack 必须在同一次审查中同步更新;
  • 修改 Grid 的固有轨道构造,需保留其文档化的 fixed、fill、fit、capped 四种状态并有聚焦测试;
  • 将成员纳入 container bleed 是独立的architecture:container-padding变更,需附带渲染兼容性证据;
  • 新组件加入的唯一条件是公共责任满足成员规则——使用 flexbox、grid 或共享工具函数不足以为凭。

决策记录:DEC-1

契约收录了一条已批准的决策(2026-08-30,决策人cixzhang):

组合原语与结构区域有各自的所有者。Stack、Grid、Center 及其修饰器组成 layout-primitives 家族;Section、Layout 区域与 Toolbar 有独立的结构区域所有者。这让成员资格可预测:原语规则描述任意子内容的组合,而不把槽位、表面或工具栏语义塞进同一契约。

验证地图:不变量如何被测试

契约提供了逐条不变量的验证地图,同时坦诚标注了"已证明"与"缺失证据":

契约验证方式证据证明的内容缺失证据
FR1, FR3Stack/Center 源码 + padding 类集测试当前合并顺序:edge > axis > uniform;等价写法产出等价类集无浏览器矩阵比较跨成员的计算值及两种书写方向
FR2Stack/Center 的逻辑属性源码声明实现用 inline-start/end 而非物理 left/right当前测试未在 LTR 与 RTL 下渲染 padding 阶梯
FR4Stack/Grid 源码 + 本地测试API 保持 gap 与 padding 分离;Grid 接受 uniform 与轴级 gap propsGrid gap 测试只断言渲染成功而非计算间距;无测试将 step 与 Stack 比较
FR5Stack/Grid/Center 源码 + 本地渲染测试每个成员当前都通过自己的排列模型路由对齐Stack/Grid 测试未断言接受值的计算对齐
FR6StackItem/GridSpan 源码 + 本地测试size="fill"映射为 fill 样式;滚动改变类输出;GridSpan 断言精确的 inline 行列跨距StackItem 的 fill 测试只断言渲染内容;无集成测试证明修饰器覆盖父组件的每种状态
FR7Grid 精确轨道输出测试 + Stack/Center 源码Grid 的 fixed/intrinsic 轨道字符串被固定;Stack 仅在配置时换行;Center 无断点路径无跨成员响应式集成矩阵
FR8对照architecture:container-padding的源码审查Stack/Center 应用本地 padding 而不发布容器 inset 变量无浏览器断言证明 Divider/Table 后代的非 bleed 行为

对应的测试文件即契约 front matter 中的verified_by列表:Stack.test.tsx、StackItem.test.tsx、Grid.test.tsx、Center.test.tsx。

契约的诚实表述值得关注:测试是组件局部的,且若干测试只断言渲染成功或类变化,并不证明计算后的 gap、对齐、逻辑方向或跨组件一致性——那些被点名列为验证缺口,而非隐式覆盖。这意味着贡献者补测试的空间是明确标出的。

内容边界:这份契约不做什么

最后,契约划定了自己的内容边界,防止被误读为组件总规范:

  • 不重复组件的 prop 表(请读各成员的.spec.md,如 Stack.spec.md、Grid.spec.md、Center.spec.md);
  • 不规定实现机制;
  • 不定义结构区域(那是 Section/Layout/Toolbar 的家族职责);
  • 不指派响应式断点;
  • 不拥有主题 anatomy 与 targets(属architecture:component-theming-surface)。

当前契约没有未决问题(Open questions: None)——采用表列出的缺失能力与验证缺口是"待办事实",不是悬而未决的家族政策。

小结

Astryx 的 layout-primitives 家族把"排列任意内容"这件最简单也最容易被做乱的事,收敛为一份可审查、可验证、可演进的契约:成员资格看公共职责,共享词汇由SpacingStep/SizeValue与排列模型唯一解释,九条不变量 + 七条允许差异 + 一张验证地图共同保证——无论是用 Stack 排一维、Grid 排二维、Center 居中,还是用 StackItem/GridSpan 微调子元素,写出来的代码在间距、对齐、逻辑方向、padding 优先级上都说着同一种语言。这份契约的完整文本与所有相关决策记录,可在 docs/families/layout-primitives.md 及其引用的架构文档(container-padding、public-component-api、component-theming-surface)中继续追溯。

【免费下载链接】astryxAn open source design system that's fully customizable and agent ready项目地址: https://gitcode.com/GitHub_Trending/as/astryx

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

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/9/15 20:33:37

AI智能博客系统开发:全栈架构与核心技术解析

1. 项目概述&#xff1a;AI智能博客开发全景图在内容创作领域&#xff0c;AI技术正从辅助工具升级为核心生产力。这个全栈项目将带你构建一个能自动生成、优化并交互的智能博客系统&#xff0c;涵盖从前端展示到AI集成的完整技术链。不同于传统博客开发&#xff0c;我们需要解决…

作者头像 李华
网站建设 2026/9/15 20:33:34

Python第五次作业避坑指南:类型转换与字符串处理

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

作者头像 李华
网站建设 2026/9/15 20:32:38

AI从工具到伙伴的演变与伦理挑战

1. 从工具到伙伴&#xff1a;AI发展历程中的角色演变人类与工具的关系始终处于动态变化中。石器时代的燧石、工业时代的蒸汽机&#xff0c;再到信息时代的计算机&#xff0c;每一次技术革命都在重塑这种关系。如今&#xff0c;AI技术的突飞猛进正在书写新的篇章——从最初简单的…

作者头像 李华
网站建设 2026/9/15 20:31:12

无心磨削工艺参数优化:Matlab多目标建模与产线闭环控制

简介&#xff1a;本资源是一套面向计算机、电子信息工程及数学等专业本科生的无心磨削工艺参数优化实践方案&#xff0c;适用于课程设计、期末大作业或毕业设计参考&#xff0c;聚焦于利用Matlab建模与数值优化解决实际制造工艺中的参数寻优问题。压缩包共2个文件&#xff08;1…

作者头像 李华