Skip to content

Commit bf6a6d9

Browse files
ntuckercursoragent
andcommitted
Simplify mediaScale follow-through and spacing audit plumbing.
Drop unused context/API surface, share size axes with mediaScale, and make the audit script reuse a page with proper cleanup. Co-authored-by: Cursor <cursoragent@cursor.com>
1 parent 435ab73 commit bf6a6d9

18 files changed

Lines changed: 141 additions & 212 deletions

File tree

‎apps/docs/src/fixtures/AppSkeleton.tsx‎

Lines changed: 11 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -145,19 +145,17 @@ export function AppSkeleton({
145145
data-narrow={narrow || undefined}
146146
data-region="sidebar"
147147
>
148-
<Stack gap="4">
149-
<Stack gap="2">
150-
<Stack gap="1">
151-
<Text role="label">Navigation</Text>
152-
<Separator />
153-
</Stack>
154-
<Stack gap="1">
155-
{['Overview', 'Projects', 'Settings'].map((item) => (
156-
<Box key={item} className={navItemClass}>
157-
<Text role="caption">{item}</Text>
158-
</Box>
159-
))}
160-
</Stack>
148+
<Stack gap="2">
149+
<Stack gap="1">
150+
<Text role="label">Navigation</Text>
151+
<Separator />
152+
</Stack>
153+
<Stack gap="1">
154+
{['Overview', 'Projects', 'Settings'].map((item) => (
155+
<Box key={item} className={navItemClass}>
156+
<Text role="caption">{item}</Text>
157+
</Box>
158+
))}
161159
</Stack>
162160
</Stack>
163161
</Box>

‎apps/docs/src/fixtures/SettingsForm.tsx‎

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -133,11 +133,13 @@ export function SettingsForm({
133133
</RadioGroup.Root>
134134
</Field.Root>
135135

136-
<Field.Root disabled={disabled} controlId="marketing">
137-
<Inline gap="2" align="center">
138-
<Checkbox defaultChecked />
139-
<Field.Label>Email me product updates</Field.Label>
140-
</Inline>
136+
<Field.Root
137+
disabled={disabled}
138+
controlId="marketing"
139+
orientation="horizontal"
140+
>
141+
<Checkbox defaultChecked />
142+
<Field.Label>Email me product updates</Field.Label>
141143
</Field.Root>
142144

143145
<Field.Root disabled={disabled}>

‎packages/silk-core/src/recipes/avatar.ts‎

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3,10 +3,14 @@ import {
33
type Recipe,
44
type VariantProps,
55
} from './defineRecipe.js';
6+
import { mediaScaleSizes } from './mediaScale.js';
67

7-
const avatarVariants = {
8-
size: ['sm', 'md', 'lg'] as const,
9-
shape: ['circle', 'rounded', 'square'] as const,
8+
const avatarVariants: {
9+
readonly size: typeof mediaScaleSizes;
10+
readonly shape: readonly ['circle', 'rounded', 'square'];
11+
} = {
12+
size: mediaScaleSizes,
13+
shape: ['circle', 'rounded', 'square'],
1014
};
1115

1216
export const avatarRecipe: Recipe<typeof avatarVariants> = defineRecipe({

‎packages/silk-core/src/recipes/comment.ts‎

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,9 +3,12 @@ import {
33
type Recipe,
44
type VariantProps,
55
} from './defineRecipe.js';
6+
import { mediaScaleSizes } from './mediaScale.js';
67

7-
const commentVariants = {
8-
size: ['sm', 'md', 'lg'] as const,
8+
const commentVariants: {
9+
readonly size: typeof mediaScaleSizes;
10+
} = {
11+
size: mediaScaleSizes,
912
};
1013

1114
export const commentRecipe: Recipe<typeof commentVariants> = defineRecipe({

‎packages/silk/src/components/Avatar.tsx‎

Lines changed: 2 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -22,12 +22,6 @@ export interface AvatarProps
2222
* Off the space scale on purpose: `density` rescales whitespace, and a face is
2323
* content — compacting a layout should not shrink the person in it.
2424
*/
25-
const sizeMap = {
26-
sm: `${mediaScale.sm.media}px`,
27-
md: `${mediaScale.md.media}px`,
28-
lg: `${mediaScale.lg.media}px`,
29-
} as const;
30-
3125
const radiusMap = {
3226
circle: 'var(--silk-radius-full)',
3327
rounded: 'var(--silk-radius-md)',
@@ -38,7 +32,7 @@ const sizeRules: string = avatarRecipe.variants.size
3832
.map(
3933
(size) => `
4034
&:where([data-size='${size}']) {
41-
--_size: ${sizeMap[size]};
35+
--_size: ${mediaScale[size].media}px;
4236
}
4337
`,
4438
)
@@ -55,7 +49,7 @@ const shapeRules: string = avatarRecipe.variants.shape
5549
.join('\n');
5650

5751
const avatarClass: string = css`
58-
--_size: ${sizeMap.md};
52+
--_size: ${mediaScale.md.media}px;
5953
--_resolved-size: var(--silk-avatar-size, var(--_size));
6054
display: inline-flex;
6155
align-items: center;

‎packages/silk/src/components/Comment.tsx‎

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -228,13 +228,11 @@ export interface CommentComponent {
228228
Header: typeof CommentHeader;
229229
Body: typeof CommentBody;
230230
Actions: typeof CommentActions;
231-
Replies: typeof CommentReplies;
232231
}
233232

234233
export const Comment: CommentComponent = Object.assign(CommentConvenience, {
235234
Root: CommentRoot,
236235
Header: CommentHeader,
237236
Body: CommentBody,
238237
Actions: CommentActions,
239-
Replies: CommentReplies,
240238
});

‎packages/silk/src/components/CommentThread.tsx‎

Lines changed: 1 addition & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -10,10 +10,6 @@ const listClass: string = css`
1010
list-style: none;
1111
`;
1212

13-
const listItemClass: string = css`
14-
list-style: none;
15-
`;
16-
1713
const continueButtonClass: string = css`
1814
align-self: flex-start;
1915
`;
@@ -95,7 +91,7 @@ function CommentThreadItem({
9591
) : undefined;
9692

9793
return (
98-
<li className={listItemClass}>
94+
<li>
9995
<Comment
10096
model={comment}
10197
onAction={(actionId) => {

‎packages/silk/src/components/EmptyState.tsx‎

Lines changed: 1 addition & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,6 @@ function useEmptyStateContext(): EmptyStateContextValue {
3636
const gapBySize = { sm: '4', md: '5', lg: '6' } as const;
3737
/** Inside the copy block, so the title and description read as one unit. */
3838
const copyGapBySize = { sm: '1', md: '2', lg: '2' } as const;
39-
const headingBySize = { sm: 'sm', md: 'md', lg: 'lg' } as const;
4039

4140
export interface EmptyStateRootProps
4241
extends ComponentPropsWithoutRef<'div'>, EmptyStateVariantProps {
@@ -94,12 +93,7 @@ function EmptyStateTitle({
9493
}: EmptyStateTitleProps): JSX.Element {
9594
const { size } = useEmptyStateContext();
9695
return (
97-
<Heading
98-
level="2"
99-
size={headingBySize[size]}
100-
className={className}
101-
{...props}
102-
>
96+
<Heading level="2" size={size} className={className} {...props}>
10397
{children}
10498
</Heading>
10599
);

‎packages/silk/src/components/Identity.tsx‎

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
import {
2+
mediaObjectRecipe,
23
mediaScale,
34
type IdentityModel,
45
type MediaScaleSize,
@@ -46,7 +47,7 @@ function IdentityRoot({
4647
...props
4748
}: IdentityRootProps): JSX.Element {
4849
const defaults = useComponentDefaults('Identity');
49-
const resolvedSize = size ?? defaults.size ?? 'md';
50+
const resolvedSize = size ?? defaults.size ?? mediaObjectRecipe.defaults.size;
5051

5152
return (
5253
<IdentityContext.Provider value={{ size: resolvedSize }}>

‎packages/silk/src/components/MediaObject.tsx‎

Lines changed: 5 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,6 @@ import {
22
mediaObjectRecipe,
33
mediaScale,
44
type MediaObjectVariantProps,
5-
type MediaScaleSize,
65
} from '@reactive/silk-core';
76
import { Slot } from 'radix-ui';
87
import {
@@ -17,23 +16,15 @@ import { useComponentDefaults } from '../theme/SilkProvider';
1716
import { Inline } from './Inline';
1817
import { Stack } from './Stack';
1918

20-
interface MediaObjectContextValue {
21-
readonly align: NonNullable<MediaObjectVariantProps['align']>;
22-
readonly gap: NonNullable<MediaObjectVariantProps['gap']>;
23-
readonly mediaPosition: NonNullable<MediaObjectVariantProps['mediaPosition']>;
24-
readonly size: MediaScaleSize;
25-
}
26-
27-
const MediaObjectContext = createContext<MediaObjectContextValue | null>(null);
19+
/** Presence-only — compound parts consume layout from the Root, not context. */
20+
const MediaObjectContext = createContext(false);
2821

29-
function useMediaObjectContext(): MediaObjectContextValue {
30-
const ctx = useContext(MediaObjectContext);
31-
if (!ctx) {
22+
function useMediaObjectContext(): void {
23+
if (!useContext(MediaObjectContext)) {
3224
throw new Error(
3325
'MediaObject compound parts must be used within MediaObject.Root',
3426
);
3527
}
36-
return ctx;
3728
}
3829

3930
export interface MediaObjectRootProps
@@ -66,14 +57,7 @@ function MediaObjectRoot({
6657
mediaObjectRecipe.defaults.mediaPosition;
6758

6859
return (
69-
<MediaObjectContext.Provider
70-
value={{
71-
align: resolvedAlign,
72-
gap: resolvedGap,
73-
mediaPosition: resolvedMediaPosition,
74-
size: resolvedSize,
75-
}}
76-
>
60+
<MediaObjectContext.Provider value={true}>
7761
<Inline
7862
{...props}
7963
asChild={asChild}

0 commit comments

Comments
 (0)