Loading...
Loading...
Guide for using Sentry's layout and text primitives. Use when implementing UI components, layouts, or typography. Enforces use of core components over styled components.
npx skill4agent add getsentry/sentry design-system@sentry/scraps/static/app/components/core/layout/container.tsxflex.tsxgrid.tsxstack.tsx/static/app/components/core/text/text.tsxheading.tsxImportant:,Flex, andGridall extendStack. This means every prop available on Container is also available on Flex, Grid, and Stack. When you useContainer, you get all Container props (position, padding, border, overflow, etc.) PLUS the flex-specific props. The same applies to Grid and Stack.<Flex>
container.tsxpositionpaddingpaddingToppaddingBottompaddingLeftpaddingRightmarginmarginTopwidthheightminWidthmaxWidthminHeightmaxHeightborderborderTopborderBottomborderLeftborderRightradiusoverflowoverflowXoverflowYbackgrounddisplayflexflexGrowflexShrinkflexBasisalignSelforderarearowcolumnimport {Container} from '@sentry/scraps/layout';
// ❌ Don't create styled components
const Component = styled('div')`
padding: ${space(2)};
border: 1px solid ${p => p.theme.tokens.border.primary};
`;
// ✅ Use Container primitive
<Container padding="md" border="primary">
Content
</Container>;<Flex>Containerflex.tsxdirectionalignjustifygap"${SpaceSize} ${SpaceSize}"wrapdisplaypositionpaddingmarginwidthheightborderradiusoverflowbackgroundimport {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>;<Grid>Containergrid.tsxcolumnsrowsareasgap"${SpaceSize} ${SpaceSize}"alignalignContentjustifyjustifyItemsflowautoColumnsautoRowspositionpaddingmarginwidthheightborderradiusoverflowbackgroundimport {Grid} from '@sentry/scraps/layout';
// ❌ Don't create styled components
const Component = styled('div')`
display: grid;
grid-template-columns: repeat(3, 1fr);
gap: ${space(2)};
`;
// ✅ Use Grid primitive
<Grid columns="repeat(3, 1fr)" gap="md">
<Item1 />
<Item2 />
<Item3 />
</Grid>;<Stack>Flexdirection="column"Stack.Separatorstack.tsxdirectionStack.Separatorimport {Stack} from '@sentry/scraps/layout';
// ❌ Don't create styled components for vertical layouts
const Component = styled('div')`
display: flex;
flex-direction: column;
gap: ${space(2)};
`;
// ✅ 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>;<Text><p><span><div>text.tsxassizevariantalignbolditalicuppercasemonospacetabularellipsiswraptextWrapwordBreakdensityunderlinestrikethroughimport {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.fontSizes.small};
`;
// ❌ 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><Heading><h1><h2>heading.tsxassizevariantalignitalicmonospacetabularellipsiswraptextWrapwordBreakdensityunderlinestrikethroughbolduppercaseimport {Heading} from '@sentry/scraps/text';
// ❌ Don't style heading elements
const Title = styled('h2')`
font-size: ${p => p.theme.fontSize.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>⚠️ CRITICAL: ALWAYS prompt the user for confirmation before creating abstractions over layout primitives (,Container,Flex,Grid,Stack,Text) when the intent is to DRY (Don't Repeat Yourself) repeated props.Heading
TableCellFleximport {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 */}extends FlexProps{...props}// ❌ 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'}}>margingap// ❌ Don't use margin between children
const Child = styled('div')`
margin-right: ${p => p.theme.spacing.lg};
`;
// ✅ Use gap on parent container
<Flex gap="lg">
<Child1 />
<Child2 />
</Flex>;// ❌ 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.fontSize.lg};
`;
// ✅ Split into layout and typography primitives
<Flex direction="column">
<Text variant="muted" size="lg">
Content
</Text>
</Flex>;/static/app/components/core/layout/container.tsx/static/app/components/core/layout/flex.tsx/static/app/components/core/layout/grid.tsx/static/app/components/core/layout/stack.tsx/static/app/components/core/text/text.tsx/static/app/components/core/text/heading.tsxgappadding"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"variant<Flex><Grid><Stack><Stack><Container><Text><Heading>gap