Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 8 additions & 2 deletions src/internal/style-api/__tests__/docs.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,8 @@ const marker = (name: string, tokens: string[], properties: string[] = []) =>
`/* awsui:style-api-slot name=${name} tokens=${tokens.join(', ')} properties=${properties.join(', ')} */`;

// Emulates the compiled output of `@include style-api.docs-forward($name, $component, $slot)`.
const forwardMarker = (name: string, component: string, slot: string) =>
`/* awsui:style-api-slot name=${name} component=${component} slot=${slot} */`;
const forwardMarker = (name: string, component: string, slot?: string) =>
`/* awsui:style-api-slot name=${name} component=${component}${slot ? ` slot=${slot}` : ''} */`;

// The expected docs of a token slot, with the always-present fields defaulted to empty.
const tokenSlot = (
Expand Down Expand Up @@ -83,6 +83,12 @@ test('reads a forward slot that points to another component slot', () => {
]);
});

test('reads a forward slot that points to a whole component', () => {
expect(extractStyleApiDocs(forwardMarker('statusPopover', 'popover')).slots).toEqual([
{ name: 'statusPopover', forwardsTo: { component: 'popover' } },
]);
});

test('reads token slots and forward slots together, preserving order', () => {
const css = `
${marker('root', ['color-text', 'color-background'])}
Expand Down
14 changes: 8 additions & 6 deletions src/internal/style-api/docs.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,15 +11,16 @@
//
// forward slot — `@include style-api.docs-forward($name, $component, $slot)`:
// /* awsui:style-api-slot name=<slot> component=<component> slot=<target-slot> */
// /* awsui:style-api-slot name=<slot> component=<component> */
//
// A forward slot reuses another component's slot (e.g. a nested Button) instead of owning tokens;
// the docs consumer resolves it to that component's slot, so it never goes stale.
// A forward slot reuses another component's slot (e.g. a nested Button), or the whole component when
// no slot is given, instead of owning tokens; the docs consumer resolves it, so it never goes stale.
//
// docs() also emits one description marker per described slot, token or property:
// /* awsui:style-api-description slot=<slot> kind=<slot|token|property> name=<name> text=<text> */

const MARKER =
/awsui:style-api-slot\s+name=([\w-]+)\s+(?:tokens=([^*]*?)\s+properties=([^*]*)|component=([\w-]+)\s+slot=([\w-]+)\s*)\*\//;
/awsui:style-api-slot\s+name=([\w-]+)\s+(?:tokens=([^*]*?)\s+properties=([^*]*)|component=([\w-]+)(?:\s+slot=([\w-]+))?\s*)\*\//;

const DESCRIPTION_MARKER =
/awsui:style-api-description\s+slot=([\w-]+)\s+kind=(slot|token|property)\s+name=([\w-]+)\s+text=([^*]*?)\s*\*\//;
Expand Down Expand Up @@ -71,9 +72,10 @@ export interface StyleApiTokenSlotDocs extends StyleApiSlotDocsBase {

export interface StyleApiForwardSlotDocs extends StyleApiSlotDocsBase {
/**
* The slot this one forwards to. Its tokens are whatever the referenced component's slot documents.
* The slot this one forwards to, or the whole component when `slot` is absent. Its style API is
* whatever the referenced component (slot) documents.
*/
forwardsTo: { component: string; slot: string };
forwardsTo: { component: string; slot?: string };
}

/**
Expand All @@ -100,7 +102,7 @@ export function extractStyleApiDocs(css: string): StyleApiDocs {
propertyDescriptions: {},
};
} else {
slotDocs = { name, forwardsTo: { component, slot } };
slotDocs = { name, forwardsTo: slot ? { component, slot } : { component } };
}
slots.push(slotDocs);
slotsByName.set(name, slotDocs);
Expand Down
12 changes: 8 additions & 4 deletions src/internal/style-api/index.scss
Original file line number Diff line number Diff line change
Expand Up @@ -137,8 +137,12 @@

// Documents a slot that forwards to another component's slot (e.g. a nested Button) instead of
// owning tokens. `$name` must match the component's `classNames` property entry; `$component` and
// `$slot` name the target component and its slot. The slot's tokens are whatever that target slot
// documents — resolved by the docs consumer, so this stays in sync automatically. Emits docs only.
@mixin docs-forward($name, $component, $slot) {
/* awsui:style-api-slot name=#{$name} component=#{$component} slot=#{$slot} */
// `$slot` name the target component and, optionally, its slot; without a slot the forward covers the
// whole component. Resolved by the docs consumer, so this stays in sync automatically. Emits docs only.
@mixin docs-forward($name, $component, $slot: null) {
@if $slot {
/* awsui:style-api-slot name=#{$name} component=#{$component} slot=#{$slot} */
} @else {
/* awsui:style-api-slot name=#{$name} component=#{$component} */
}
}
Loading