重要前提
安装AI Skills的关键前提是:必须科学上网,且开启TUN模式,这一点至关重要,直接决定安装能否顺利完成,在此郑重提醒三遍:科学上网,科学上网,科学上网。查看完整安装教程 →
design-system by getsentry/sentry
npx skills add https://github.com/getsentry/sentry --skill design-system始终使用来自 @sentry/scraps 的核心组件,而不是用 Emotion 创建样式化组件。
核心组件在整个代码库中提供一致的样式、响应式设计和更好的可维护性。
有关支持的完整属性列表及其类型,请参考实现文件:
/static/app/components/core/layout/
container.tsx - 包含所有布局属性的基础容器flex.tsx - 弹性布局基础组件grid.tsx - 网格布局基础组件stack.tsx - 堆叠布局基础组件(默认采用列方向的弹性布局)/static/app/components/core/text/
广告位招租
在这里展示您的产品或服务
触达数万 AI 开发者,精准高效
text.tsx - 文本基础组件heading.tsx - 标题基础组件重要:
Flex、Grid和Stack都继承自Container。这意味着 Container 上可用的所有属性在 Flex、Grid 和 Stack 上也可用。当你使用<Flex>时,你会获得所有 Container 属性(位置、内边距、边框、溢出等)加上弹性布局特有的属性。Grid 和 Stack 也是如此。
支持所有常见布局属性的基础布局组件。Flex、Grid 和 Stack 继承自 Container,继承了它的所有属性。
关键属性(完整列表见 container.tsx):
position: "static" | "relative" | "absolute" | "fixed" | "sticky"padding, paddingTop, paddingBottom, paddingLeft, paddingRight: SpaceSize 令牌margin, marginTop, 等: SpaceSize 令牌(已弃用,建议使用 gap)width, height, minWidth, maxWidth, minHeight, maxHeightborder, borderTop, borderBottom, borderLeft, borderRight: BorderVariant 令牌radius: RadiusSize 令牌overflow, overflowX, overflowY: "visible" | "hidden" | "scroll" | "auto"background: SurfaceVariant ("primary" | "secondary" | "tertiary")display: 各种显示类型flex, flexGrow, flexShrink, flexBasis, alignSelf, orderarea, row, columnimport {Container} from '@sentry/scraps/layout';
// ❌ 不要创建样式化组件
const Component = styled('div')`
padding: ${p => p.theme.space.md};
border: 1px solid ${p => p.theme.tokens.border.primary};
`;
// ✅ 使用 Container 基础组件
<Container padding="md" border="primary">
Content
</Container>;
使用 <Flex> 进行弹性布局。继承自 Container,继承了所有 Container 属性加上弹性布局特有的属性。
弹性布局特有属性(完整列表见 flex.tsx):
direction: "row" | "row-reverse" | "column" | "column-reverse"align: "start" | "end" | "center" | "baseline" | "stretch"justify: "start" | "end" | "center" | "between" | "around" | "evenly" | "left" | "right"gap: SpaceSize 或 "${SpaceSize} ${SpaceSize}" 用于行/列间距wrap: "nowrap" | "wrap" | "wrap-reverse"display: "flex" | "inline-flex" | "none"加上所有 Container 属性:position、padding、margin、width、height、border、radius、overflow、background、弹性/网格项目属性等(见上文 Container 部分)。
import {Flex} from '@sentry/scraps/layout';
// ❌ 不要创建样式化组件
const Component = styled('div')`
display: flex;
flex-direction: column;
position: relative;
`;
// ✅ 使用带有属性的 Flex 基础组件
<Flex direction="column" position="relative" gap="md">
<Child1 />
<Child2 />
</Flex>;
使用 <Grid> 进行网格布局。继承自 Container,继承了所有 Container 属性加上网格布局特有的属性。
网格布局特有属性(完整列表见 grid.tsx):
columns: 网格模板列(数字或 CSS 值)rows: 网格模板行areas: 命名的网格区域gap: SpaceSize 或 "${SpaceSize} ${SpaceSize}" 用于行/列间距align: "start" | "end" | "center" | "baseline" | "stretch" (align-items)alignContent: "start" | "end" | "center" | "between" | "around" | "evenly" | "stretch"justify: "start" | "end" | "center" | "between" | "around" | "evenly" | "stretch" (justify-content)justifyItems: "start" | "end" | "center" | "stretch"flow: "row" | "column" | "row dense" | "column dense"autoColumns, autoRows: 自动生成轨道的大小加上所有 Container 属性:position、padding、margin、width、height、border、radius、overflow、background、弹性/网格项目属性等(见上文 Container 部分)。
import {Grid} from '@sentry/scraps/layout';
// ❌ 不要创建样式化组件
const Component = styled('div')`
display: grid;
grid-template-columns: repeat(3, 1fr);
gap: ${p => p.theme.space.md};
`;
// ✅ 使用 Grid 基础组件
<Grid columns="repeat(3, 1fr)" gap="md">
<Item1 />
<Item2 />
<Item3 />
</Grid>;
使用 <Stack> 进行垂直布局。Stack 本质上是默认 direction="column" 的 Flex。它还提供 Stack.Separator 用于在项目之间添加分隔符。
属性(完整列表见 stack.tsx):
direction 默认为 "column"(但可以被覆盖)Stack.Separator 组件用于在堆叠项目之间添加分隔线import {Stack} from '@sentry/scraps/layout';
// ❌ 不要为垂直布局创建样式化组件
const Component = styled('div')`
display: flex;
flex-direction: column;
gap: ${p => p.theme.space.md};
`;
// ✅ 使用 Stack 基础组件(自动采用列方向)
<Stack gap="md">
<Item1 />
<Item2 />
<Item3 />
</Stack>;
// ✅ 在项目之间使用分隔符
<Stack gap="md">
<Item1 />
<Stack.Separator />
<Item2 />
<Stack.Separator />
<Item3 />
</Stack>;
// ✅ Stack 支持所有 Flex 和 Container 属性
<Stack gap="md" padding="lg" position="relative" border="primary">
<Item1 />
<Item2 />
</Stack>;
使用 <Text> 处理所有文本内容。切勿使用原始的 <p>、<span> 或带有文本样式的 <div> 元素。
关键属性(完整列表见 text.tsx):
as: "span" | "p" | "label" | "div"(语义化 HTML 元素)size: TextSize ("xs" | "sm" | "md" | "lg" | "xl" | "2xl")variant: ContentVariant | "muted"(见下文内容变体令牌)align: "left" | "center" | "right" | "justify"bold: booleanitalic: booleanuppercase: booleanmonospace: booleantabular: boolean(固定宽度数字)ellipsis: boolean(用省略号截断)wrap: "nowrap" | "normal" | "pre" | "pre-line" | "pre-wrap"textWrap: "wrap" | "nowrap" | "balance" | "pretty" | "stable"wordBreak: "normal" | "break-all" | "keep-all" | "break-word"density: "compressed" | "comfortable"(行高)underline: boolean | "dotted"strikethrough: booleanimport {Text} from '@sentry/scraps/text';
// ❌ 不要创建样式化文本组件
const Label = styled('span')`
color: ${p => p.theme.tokens.content.secondary};
font-size: ${p => p.theme.font.size.sm};
`;
// ❌ 不要使用原始元素
<p>This is a paragraph</p>
<span>Status: Active</span>
// ✅ 使用带有语义化 'as' 属性的 Text 基础组件
<Text as="p" variant="muted" density="comfortable">
This is a paragraph
</Text>
<Text as="span" bold uppercase>
Status: Active
</Text>
使用 <Heading> 处理所有标题。切勿使用原始的 <h1>、<h2> 等元素。
关键属性(完整列表见 heading.tsx):
as: "h1" | "h2" | "h3" | "h4" | "h5" | "h6"(必需)size: HeadingSize ("xs" | "sm" | "md" | "lg" | "xl" | "2xl" | "3xl" | "4xl")variant: 与 Text 相同align: 与 Text 相同italic, monospace, tabular: 与 Text 相同ellipsis, wrap, textWrap, wordBreak: 与 Text 相同density: 与 Text 相同underline, strikethrough: 与 Text 相同注意:bold 和 uppercase 在 Heading 上不可用(标题始终是粗体)。
import {Heading} from '@sentry/scraps/text';
// ❌ 不要样式化标题元素
const Title = styled('h2')`
font-size: ${p => p.theme.font.size.md};
font-weight: bold;
`;
// ❌ 不要使用原始标题元素
<h2>My Title</h2>
// ✅ 使用带有语义化 'as' 属性的 Heading 基础组件
<Heading as="h2">My Title</Heading>
// ✅ 使用自定义大小
<Heading as="h3" size="xl">Large H3</Heading>
重要:始终优先使用
InfoTip和InfoText,而不是原始的<Tooltip>组件。这些组件为上下文帮助提供了一致、可访问的模式。
使用 <InfoTip> 在标签或标题旁边添加带有工具提示的信息图标。它支持键盘访问,并为补充帮助提供一致的模式。
import {InfoTip} from '@sentry/scraps/info';
import {Flex} from '@sentry/scraps/layout';
import {Text} from '@sentry/scraps/text';
// ❌ 不要使用带有任意图标的 Tooltip
<Flex gap="xs" align="center">
<Text>Retention Period</Text>
<Tooltip title="The number of days...">
<IconInfo size="xs" />
</Tooltip>
</Flex>
// ✅ 使用 InfoTip 获取上下文帮助图标
<Flex gap="xs" align="center">
<Text>Retention Period</Text>
<InfoTip title="The number of days event data is stored before being automatically deleted." />
</Flex>
关键属性:
title: 工具提示内容(必需)size: "xs" | "sm"(默认)| "md"使用时机:
使用 <InfoText> 处理带有工具提示的内联文本。它渲染带有虚线下划线的文本,悬停/聚焦时显示工具提示。
import {InfoText} from '@sentry/scraps/info';
// ❌ 不要用原始 Tooltip 包装文本
<Tooltip title="Time to First Byte measures the time...">
<span style={{textDecoration: 'underline dotted'}}>TTFB</span>
</Tooltip>
// ✅ 使用 InfoText 进行内联解释
<InfoText title="Time to First Byte measures the time from the request start until the first byte of the response is received.">
TTFB
</InfoText>
关键属性:
title: 工具提示内容(必需)Text,因此支持所有 Text 属性:size、variant、bold 等。// 使用文本样式属性
<InfoText title="Small muted text" size="sm" variant="muted">
Hint text
</InfoText>
<InfoText title="Bold text" bold>
Important term
</InfoText>
使用时机:
⚠️ 关键:当意图是 DRY(不要重复自己)重复的属性时,在创建布局基础组件(
Container、Flex、Grid、Stack、Text、Heading)的抽象层之前,必须始终提示用户进行确认。
你可以通过使用有意义的名称(例如 TableCell 与通用的 Flex)来创建基础组件的精简抽象层,目的是改进语义结构并提供一些默认属性。非常重要的是,你应该谨慎地这样做,并且只有在它能显著提高可读性时才这样做。例如,如果重复的属性只有两个实例,并且它们彼此相邻,那么抽象的成本就超过了简洁性的收益。
在创建抽象层之前,你必须:
import {Flex, type FlexProps} from '@sentry/scraps/layout';
// ❌ 不要在所有地方重复相同的属性
<Flex align="center" gap="xs" flex="1" padding="sm">Content 1</Flex>
<Flex align="center" gap="xs" flex="1" padding="sm">Content 2</Flex>
<Flex align="center" gap="xs" flex="1" padding="sm">Content 3</Flex>
<Flex align="center" gap="xs" flex="1" padding="sm">Content 4</Flex>
// ✅ 创建一个带有默认属性的精简包装器(在用户确认之后)
function TableCell(props: FlexProps) {
return <Flex align="center" gap="md" {...props} />;
}
<TableCell>Content 1</TableCell>
<TableCell>Content 2</TableCell>
<TableCell align="start">Content 3</TableCell>{/* 可以覆盖默认值 */}
关键点:
extends FlexProps){...props} 以允许覆盖大多数属性支持使用断点键的响应式语法。
// ❌ 不要使用样式化的媒体查询
const Component = styled('div')`
display: flex;
flex-direction: column;
@media screen and (min-width: ${p => p.theme.breakpoints.md}) {
flex-direction: row;
}
`;
// ✅ 使用响应式属性签名
<Flex direction={{xs: 'column', md: 'row'}}>
Container 支持 margin 属性,但它们已弃用。请改用父容器上的 gap。
// ❌ 不要在子元素之间使用 margin
const Child = styled('div')`
margin-right: ${p => p.theme.space.lg};
`;
// ✅ 在父容器上使用 gap
<Flex gap="lg">
<Child1 />
<Child2 />
</Flex>;
不要将布局和排版耦合在单个样式化组件中。使用单独的基础组件。
// ❌ 不要将布局和排版耦合在一起
const Component = styled('div')`
display: flex;
flex-direction: column;
color: ${p => p.theme.tokens.content.secondary};
font-size: ${p => p.theme.font.size.lg};
`;
// ✅ 拆分为布局和排版基础组件
<Flex direction="column">
<Text variant="muted" size="lg">
Content
</Text>
</Flex>;
实现文件包含支持的完整、最新的属性列表以及 TypeScript 类型。如有疑问:
/static/app/components/core/layout/container.tsx 获取基础布局属性/static/app/components/core/layout/flex.tsx 获取 Flex 特有属性/static/app/components/core/layout/grid.tsx 获取 Grid 特有属性/static/app/components/core/layout/stack.tsx 获取 Stack 特有属性/static/app/components/core/text/text.tsx 获取 Text 属性/static/app/components/core/text/heading.tsx 获取 Heading 属性用于 gap、padding:
"0"、"2xs"、"xs"、"sm"、"md"、"lg"、"xl"、"2xl"、"3xl""md lg"(垂直 水平){{xs: "sm", md: "lg"}}用于 border 属性:
"primary"、"muted"、"accent"、"danger"、"promotion"、"success"、"warning"用于 radius 属性:
"0"、"2xs"、"xs"、"sm"、"md"、"lg"、"xl"、"2xl"、"full"用于布局组件上的 background 属性:
"primary"、"secondary"、"tertiary"用于 Text 和 Heading 上的 variant 属性:
在创建样式化组件之前,请自问:
<Flex>、<Grid> 或 <Stack> 进行布局?<Stack> 进行默认列方向的垂直布局?<Container> 处理边框/内边距/定位?<Text> 或 <Heading> 进行排版?<InfoTip> 或 <InfoText> 代替 <Tooltip>?gap 代替 margin?如果你对其中任何一个问题回答是,请使用基础组件代替。
每周安装量
78
代码仓库
GitHub 星标
43.5K
首次出现
2026年2月11日
安全审计
安装于
github-copilot75
opencode75
gemini-cli74
cursor74
codex74
kimi-cli73
ALWAYS use core components from@sentry/scraps instead of creating styled components with Emotion.
Core components provide consistent styling, responsive design, and better maintainability across the codebase.
For the complete list of supported props and their types, refer to the implementation files:
/static/app/components/core/layout/
container.tsx - Base container with all layout propsflex.tsx - Flex layout primitivegrid.tsx - Grid layout primitivestack.tsx - Stack layout primitive (Flex with column direction by default)/static/app/components/core/text/
text.tsx - Text primitiveheading.tsx - Heading primitiveImportant :
Flex,Grid, andStackall extendContainer. This means every prop available on Container is also available on Flex, Grid, and Stack. When you use<Flex>, you get all Container props (position, padding, border, overflow, etc.) PLUS the flex-specific props. The same applies to Grid and Stack.
Base layout component that supports all common layout properties. Flex, Grid, and Stack extend Container, inheriting all of its props.
Key Props (see container.tsx for complete list):
position: "static" | "relative" | "absolute" | "fixed" | "sticky"
padding, paddingTop, paddingBottom, paddingLeft, paddingRight: SpaceSize tokens
margin, marginTop, etc.: SpaceSize tokens (deprecated, prefer gap)
width, height, , , ,
Use <Flex> for flex layouts. Extends Container, inheriting all Container props plus flex-specific props.
Flex-Specific Props (see flex.tsx for complete list):
direction: "row" | "row-reverse" | "column" | "column-reverse"align: "start" | "end" | "center" | "baseline" | "stretch"justify: "start" | "end" | "center" | "between" | "around" | "evenly" | "left" | "right"gap: SpaceSize or "${SpaceSize} ${SpaceSize}" for row/column gapwrap: "nowrap" | "wrap" | "wrap-reverse"display: "flex" | "inline-flex" | "none"Plus ALL Container props : position, padding, margin, width, height, border, radius, overflow, background, flex/grid item props, and more (see Container section above).
import {Flex} from '@sentry/scraps/layout';
// ❌ Don't create styled components
const Component = styled('div')`
display: flex;
flex-direction: column;
position: relative;
`;
// ✅ Use Flex primitive with props
<Flex direction="column" position="relative" gap="md">
<Child1 />
<Child2 />
</Flex>;
Use <Grid> for grid layouts. Extends Container, inheriting all Container props plus grid-specific props.
Grid-Specific Props (see grid.tsx for complete list):
columns: Grid template columns (number or CSS value)rows: Grid template rowsareas: Named grid areasgap: SpaceSize or "${SpaceSize} ${SpaceSize}" for row/column gapalign: "start" | "end" | "center" | "baseline" | "stretch" (align-items)alignContent: "start" | "end" | "center" | "between" | "around" | "evenly" | "stretch"justify: "start" | "end" | "center" | "between" | "around" | "evenly" | "stretch" (justify-content)justifyItems: "start" | "end" | "center" | "stretch"Plus ALL Container props : position, padding, margin, width, height, border, radius, overflow, background, flex/grid item props, and more (see Container section above).
import {Grid} from '@sentry/scraps/layout';
// ❌ Don't create styled components
const Component = styled('div')`
display: grid;
grid-template-columns: repeat(3, 1fr);
gap: ${p => p.theme.space.md};
`;
// ✅ Use Grid primitive
<Grid columns="repeat(3, 1fr)" gap="md">
<Item1 />
<Item2 />
<Item3 />
</Grid>;
Use <Stack> for vertical layouts. Stack is essentially Flex with direction="column" by default. It also provides Stack.Separator for adding separators between items.
Props (see stack.tsx for complete list):
Same as Flex props (inherits all Flex and Container props)
direction defaults to "column" (but can be overridden)
Stack.Separator component for adding dividers between stack items
import {Stack} from '@sentry/scraps/layout';
// ❌ Don't create styled components for vertical layouts
const Component = styled('div') display: flex; flex-direction: column; gap: ${p => p.theme.space.md};;
// ✅ Use Stack primitive (automatically column direction) <Stack gap="md"> <Item1 /> <Item2 /> <Item3 /> </Stack>;
// ✅ With separators between items <Stack gap="md"> <Item1 /> <Stack.Separator /> <Item2 /> <Stack.Separator /> <Item3 /> </Stack>;
// ✅ Stack supports all Flex and Container props <Stack gap="md" padding="lg" position="relative" border="primary"> <Item1 /> <Item2 /> </Stack>;
Use <Text> for all text content. Never use raw <p>, <span>, or <div> elements with text styling.
Key Props (see text.tsx for complete list):
as: "span" | "p" | "label" | "div" (semantic HTML element)
size: TextSize ("xs" | "sm" | "md" | "lg" | "xl" | "2xl")
variant: ContentVariant | "muted" (see Content Variant Tokens below)
align: "left" | "center" | "right" | "justify"
bold: boolean
italic: boolean
uppercase: boolean
monospace: boolean
Use <Heading> for all headings. Never use raw <h1>, <h2>, etc. elements.
Key Props (see heading.tsx for complete list):
as: "h1" | "h2" | "h3" | "h4" | "h5" | "h6" (REQUIRED)size: HeadingSize ("xs" | "sm" | "md" | "lg" | "xl" | "2xl" | "3xl" | "4xl")variant: Same as Textalign: Same as Textitalic, monospace, tabular: Same as Textellipsis, wrap, textWrap, wordBreak: Same as TextNote: bold and uppercase are NOT available on Heading (headings are always bold).
import {Heading} from '@sentry/scraps/text';
// ❌ Don't style heading elements
const Title = styled('h2')`
font-size: ${p => p.theme.font.size.md};
font-weight: bold;
`;
// ❌ Don't use raw heading elements
<h2>My Title</h2>
// ✅ Use Heading primitive with semantic 'as' prop
<Heading as="h2">My Title</Heading>
// ✅ With custom size
<Heading as="h3" size="xl">Large H3</Heading>
Important : Always prefer
InfoTipandInfoTextover using raw<Tooltip>components. These provide consistent, accessible patterns for contextual help.
Use <InfoTip> to add an info icon with tooltip next to labels or headings. It's keyboard accessible and provides a consistent pattern for supplementary help.
import {InfoTip} from '@sentry/scraps/info';
import {Flex} from '@sentry/scraps/layout';
import {Text} from '@sentry/scraps/text';
// ❌ Don't use Tooltip with arbitrary icons
<Flex gap="xs" align="center">
<Text>Retention Period</Text>
<Tooltip title="The number of days...">
<IconInfo size="xs" />
</Tooltip>
</Flex>
// ✅ Use InfoTip for contextual help icons
<Flex gap="xs" align="center">
<Text>Retention Period</Text>
<InfoTip title="The number of days event data is stored before being automatically deleted." />
</Flex>
Key Props :
title: Tooltip content (required)size: "xs" | "sm" (default) | "md"When to Use :
Use <InfoText> for inline text with a tooltip. It renders text with a dotted underline that reveals a tooltip on hover/focus.
import {InfoText} from '@sentry/scraps/info';
// ❌ Don't wrap text with raw Tooltip
<Tooltip title="Time to First Byte measures the time...">
<span style={{textDecoration: 'underline dotted'}}>TTFB</span>
</Tooltip>
// ✅ Use InfoText for inline explanations
<InfoText title="Time to First Byte measures the time from the request start until the first byte of the response is received.">
TTFB
</InfoText>
Key Props :
title: Tooltip content (required)
Extends Text, so supports all Text props: size, variant, bold, etc.
// With Text styling props <InfoText title="Small muted text" size="sm" variant="muted"> Hint text </InfoText> <InfoText title="Bold text" bold> Important term </InfoText>
When to Use :
⚠️ CRITICAL: ALWAYS prompt the user for confirmation before creating abstractions over layout primitives (
Container,Flex,Grid,Stack,Text,Heading) when the intent is to DRY (Don't Repeat Yourself) repeated props.
You can create thin abstractions over primitives with the purpose of improving the semantic structure by using meaningful names (e.g., TableCell vs generic Flex) and with the purpose of providing some default props. It is very important that you do this sparingly, and only when it is a net gain for readability. For example, if there are only two instances of the duplicated props, and they are placed next to each other, the price of the abstraction outweights the terseness.
Before creating an abstraction, you MUST:
import {Flex, type FlexProps} from '@sentry/scraps/layout';
// ❌ Don't repeat the same props everywhere
<Flex align="center" gap="xs" flex="1" padding="sm">Content 1</Flex>
<Flex align="center" gap="xs" flex="1" padding="sm">Content 2</Flex>
<Flex align="center" gap="xs" flex="1" padding="sm">Content 3</Flex>
<Flex align="center" gap="xs" flex="1" padding="sm">Content 4</Flex>
// ✅ Create a thin wrapper with default props (AFTER USER CONFIRMATION)
function TableCell(props: FlexProps) {
return <Flex align="center" gap="md" {...props} />;
}
<TableCell>Content 1</TableCell>
<TableCell>Content 2</TableCell>
<TableCell align="start">Content 3</TableCell>{/* Can override defaults */}
Key points:
extends FlexProps){...props} to allow overridesMost props support responsive syntax using breakpoint keys.
// ❌ Don't use styled media queries
const Component = styled('div')`
display: flex;
flex-direction: column;
@media screen and (min-width: ${p => p.theme.breakpoints.md}) {
flex-direction: row;
}
`;
// ✅ Use responsive prop signature
<Flex direction={{xs: 'column', md: 'row'}}>
Container supports margin props but they are deprecated. Use gap on parent containers instead.
// ❌ Don't use margin between children
const Child = styled('div')`
margin-right: ${p => p.theme.space.lg};
`;
// ✅ Use gap on parent container
<Flex gap="lg">
<Child1 />
<Child2 />
</Flex>;
Don't couple layout and typography in a single styled component. Use separate primitives.
// ❌ Don't couple layout and typography
const Component = styled('div')`
display: flex;
flex-direction: column;
color: ${p => p.theme.tokens.content.secondary};
font-size: ${p => p.theme.font.size.lg};
`;
// ✅ Split into layout and typography primitives
<Flex direction="column">
<Text variant="muted" size="lg">
Content
</Text>
</Flex>;
The implementation files contain the complete, up-to-date list of supported props with TypeScript types. When in doubt:
/static/app/components/core/layout/container.tsx for base layout props/static/app/components/core/layout/flex.tsx for Flex-specific props/static/app/components/core/layout/grid.tsx for Grid-specific props/static/app/components/core/layout/stack.tsx for Stack-specific props/static/app/components/core/text/text.tsx for Text props/static/app/components/core/text/heading.tsx for Heading propsUse these for gap, padding:
"0", "2xs", "xs", "sm", "md", "lg", "xl", "2xl", "3xl""md lg" (vertical horizontal){{xs: "sm", md: "lg"}}Use these for border prop:
"primary", "muted", "accent", "danger", "promotion", "success", "warning"Use these for radius prop:
"0", "2xs", "xs", "sm", "md", "lg", "xl", "2xl", "full"Use these for background prop on layout components:
"primary", "secondary", "tertiary"Use these for variant prop on Text and Heading:
Before creating a styled component, ask:
<Flex>, <Grid>, or <Stack> for layout?<Stack> for vertical layouts with default column direction?<Container> for borders/padding/positioning?<Text> or <Heading> for typography?<InfoTip> or <InfoText> instead of <Tooltip>?If you answered yes to any of these, use the primitive instead.
Weekly Installs
78
Repository
GitHub Stars
43.5K
First Seen
Feb 11, 2026
Security Audits
Gen Agent Trust HubPassSocketPassSnykPass
Installed on
github-copilot75
opencode75
gemini-cli74
cursor74
codex74
kimi-cli73
Caveman-Commit:遵循 Conventional Commits 规范的简洁 Git 提交信息生成工具
7,800 周安装
minWidthmaxWidthminHeightmaxHeightborder, borderTop, borderBottom, borderLeft, borderRight: BorderVariant tokens
radius: RadiusSize tokens
overflow, overflowX, overflowY: "visible" | "hidden" | "scroll" | "auto"
background: SurfaceVariant ("primary" | "secondary" | "tertiary")
display: Various display types
Flex item props: flex, flexGrow, flexShrink, flexBasis, alignSelf, order
Grid item props: area, row, column
import {Container} from '@sentry/scraps/layout';
// ❌ Don't create styled components
const Component = styled('div') padding: ${p => p.theme.space.md}; border: 1px solid ${p => p.theme.tokens.border.primary};;
// ✅ Use Container primitive <Container padding="md" border="primary"> Content </Container>;
flow: "row" | "column" | "row dense" | "column dense"autoColumns, autoRows: Size of auto-generated trackstabular: boolean (fixed-width numbers)
ellipsis: boolean (truncate with ellipsis)
wrap: "nowrap" | "normal" | "pre" | "pre-line" | "pre-wrap"
textWrap: "wrap" | "nowrap" | "balance" | "pretty" | "stable"
wordBreak: "normal" | "break-all" | "keep-all" | "break-word"
density: "compressed" | "comfortable" (line-height)
underline: boolean | "dotted"
strikethrough: boolean
import {Text} from '@sentry/scraps/text';
// ❌ Don't create styled text components
const Label = styled('span') color: ${p => p.theme.tokens.content.secondary}; font-size: ${p => p.theme.font.size.sm};;
// ❌ Don't use raw elements
<p>This is a paragraph</p> <span>Status: Active</span>// ✅ Use Text primitive with semantic 'as' prop <Text as="p" variant="muted" density="comfortable"> This is a paragraph </Text> <Text as="span" bold uppercase> Status: Active </Text>
density: Same as Textunderline, strikethrough: Same as Textgap instead of margins?