Skip to content

Commit 651e884

Browse files
authored
Merge pull request #154 from bookedsolidtech/feature/slot-styling-guidance
feat: add slot styling guidance to suggest_usage handler
2 parents 4080105 + 8c8920b commit 651e884

File tree

2 files changed

+45
-0
lines changed

2 files changed

+45
-0
lines changed

packages/core/src/handlers/suggest.ts

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -182,6 +182,7 @@ function buildStyling(
182182
meta: {
183183
cssProperties: Array<{ name: string; description: string; default?: string }>;
184184
cssParts: Array<{ name: string; description: string }>;
185+
slots: Array<{ name: string; description: string }>;
185186
},
186187
): SuggestUsageStyling | undefined {
187188
if (meta.cssProperties.length === 0 && meta.cssParts.length === 0) return undefined;
@@ -218,6 +219,35 @@ function buildStyling(
218219

219220
const warnings: string[] = getShadowDomWarnings(tagName);
220221

222+
// Add slot-specific styling guidance when the component has slots
223+
if (meta.slots.length > 0) {
224+
const namedSlots = meta.slots.filter((s) => s.name !== '');
225+
const hasDefaultSlot = meta.slots.some((s) => s.name === '');
226+
227+
warnings.push(
228+
`To style slotted content, use light DOM CSS targeting the elements BEFORE they are slotted in. Do not use \`::slotted()\` in consumer CSS — it only works inside the shadow root stylesheet.`,
229+
);
230+
231+
if (hasDefaultSlot) {
232+
warnings.push(
233+
`Default slot: style children of \`${tagName}\` in your page CSS (e.g. \`${tagName} > p { ... }\`). These selectors work because slotted elements remain in the light DOM.`,
234+
);
235+
}
236+
237+
if (namedSlots.length > 0) {
238+
const slotExample = namedSlots[0];
239+
if (slotExample) {
240+
warnings.push(
241+
`Named slots: style elements with \`[slot="${slotExample.name}"]\` attribute selector in your page CSS (e.g. \`${tagName} [slot="${slotExample.name}"] { ... }\`).`,
242+
);
243+
}
244+
}
245+
246+
warnings.push(
247+
`Slotted content inherits font styles (color, font-size, line-height) from the component's shadow DOM, but layout properties (margin, padding, display) must be set in light DOM CSS.`,
248+
);
249+
}
250+
221251
return { cssProperties, cssParts, cssSnippet, warnings };
222252
}
223253

tests/handlers/suggest.test.ts

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -712,6 +712,21 @@ describe('suggestUsage — styling section (my-button with CSS props and parts)'
712712
expect(allWarnings).toContain('Shadow DOM');
713713
});
714714

715+
it('styling.warnings include slot styling guidance for components with slots', async () => {
716+
const result = await suggestUsage('my-button', makeConfig());
717+
const allWarnings = result.styling!.warnings.join(' ');
718+
// my-button has slots, so slot styling guidance should be present
719+
expect(allWarnings).toContain('slotted content');
720+
expect(allWarnings).toContain('light DOM CSS');
721+
});
722+
723+
it('styling.warnings include named slot selectors when component has named slots', async () => {
724+
const result = await suggestUsage('my-button', makeConfig());
725+
const allWarnings = result.styling!.warnings.join(' ');
726+
// my-button has named slots (prefix, suffix)
727+
expect(allWarnings).toContain('[slot=');
728+
});
729+
715730
it('returns no styling when component has no CSS properties or parts', async () => {
716731
const noStyleCem = {
717732
schemaVersion: '1.0.0',

0 commit comments

Comments
 (0)