diff --git a/src/internal/style-api/__tests__/docs.test.ts b/src/internal/style-api/__tests__/docs.test.ts index 173f65e..38adcbe 100644 --- a/src/internal/style-api/__tests__/docs.test.ts +++ b/src/internal/style-api/__tests__/docs.test.ts @@ -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 = ( @@ -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'])} diff --git a/src/internal/style-api/docs.ts b/src/internal/style-api/docs.ts index c15b3f0..e3e5ac1 100644 --- a/src/internal/style-api/docs.ts +++ b/src/internal/style-api/docs.ts @@ -11,15 +11,16 @@ // // forward slot — `@include style-api.docs-forward($name, $component, $slot)`: // /* awsui:style-api-slot name= component= slot= */ +// /* awsui:style-api-slot name= 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= kind= name= 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*\*\//; @@ -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 }; } /** @@ -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); diff --git a/src/internal/style-api/index.scss b/src/internal/style-api/index.scss index fdb2a8c..e3b64b7 100644 --- a/src/internal/style-api/index.scss +++ b/src/internal/style-api/index.scss @@ -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} */ + } }