From 1e882e37008b254d25f78f9fe06a572248bad0fd Mon Sep 17 00:00:00 2001 From: dobromirts Date: Mon, 13 Jul 2026 09:47:44 +0300 Subject: [PATCH] feat(ApiLink): default member label to member name, cased per platform --- src/components/mdx/ApiLink/ApiLink.astro | 14 ++++++++++++-- src/components/mdx/ApiLink/README.md | 6 ++++-- 2 files changed, 16 insertions(+), 4 deletions(-) diff --git a/src/components/mdx/ApiLink/ApiLink.astro b/src/components/mdx/ApiLink/ApiLink.astro index d6951dc..1cb60c1 100644 --- a/src/components/mdx/ApiLink/ApiLink.astro +++ b/src/components/mdx/ApiLink/ApiLink.astro @@ -63,6 +63,16 @@ const ctx = Astro.locals.platformContext as PlatformContext; const { prefix, apiPackages } = ctx; const label = Astro.props.label; +const upperFirst = (value: string) => value ? value.charAt(0).toUpperCase() + value.slice(1) : value; +const lowerFirst = (value: string) => value ? value.charAt(0).toLowerCase() + value.slice(1) : value; + +/** + * Auto-label for a member when no explicit `label` is provided. Blazor member + * names are PascalCase; WebComponents, React, and Angular use camelCase. + */ +const formatMemberName = (member: string) => + ctx.name === 'Blazor' ? upperFirst(member) : lowerFirst(member); + function getIndexedDisplayName(resolvedName: string, displayBaseName: string, type: string, classSuffix?: string) { if (resolvedName === type) return type; if (classSuffix && resolvedName === `${type}${classSuffix}`) return type; @@ -109,7 +119,7 @@ if (Astro.props.kind === 'sass') { const baseType = effectivePrefixed ? `${prefix}${type}` : type; url = ''; - displayLabel = label ?? (member ? `${baseType}.${member}` : baseType); + displayLabel = label ?? (member ? formatMemberName(member) : baseType); renderCode = true; const indexed = resolveApiLinkFromIndex({ @@ -128,7 +138,7 @@ if (Astro.props.kind === 'sass') { url = indexed.url; renderLink = true; const indexedDisplay = getIndexedDisplayName(indexed.symbolName, baseType, type, pkgConfig.classSuffix); - displayLabel = label ?? (indexed.memberName ? `${indexedDisplay}.${indexed.memberName}` : indexedDisplay); + displayLabel = label ?? (indexed.memberName ? formatMemberName(indexed.memberName) : indexedDisplay); } else if (indexed.status === 'ambiguous') { const symbol = member ? `${type}.${member}` : type; throw new Error(`[ApiLink] Ambiguous API symbol "${symbol}" matched registry candidate "${indexed.candidate}". Add pkg= or kind= to disambiguate.`); diff --git a/src/components/mdx/ApiLink/README.md b/src/components/mdx/ApiLink/README.md index e030e50..c7fd56a 100644 --- a/src/components/mdx/ApiLink/README.md +++ b/src/components/mdx/ApiLink/README.md @@ -38,7 +38,7 @@ the index is unavailable, `ApiLink` renders code text and does not guess a URL. |------|------|---------|-------------| | `type` | `string` | *(required)* | Short symbol name without platform prefix, e.g. `"Grid"` instead of `"IgrGrid"`. | | `member` | `string` | — | Optional member name. Resolved through the generated member map when available. | -| `label` | `string` | auto | Override the display text. | +| `label` | `string` | auto | Override the display text. When omitted and `member` is set, the label defaults to just the member name (not `Type.member`), cased per platform: camelCase for WebComponents/React/Angular, PascalCase for Blazor. When omitted with no `member`, it defaults to the resolved symbol name. | | `pkg` | `string` | — | Ambiguity override only. Use when the same symbol exists in multiple packages and the combined index cannot choose safely. | | `kind` | `'class' \| 'interface' \| 'enum' \| 'type' \| 'variable' \| 'function'` | auto | Optional narrowing. Usually unnecessary when the index is available. | | `prefixed` | `boolean` | `true` | Candidate-name override for symbols that are never platform-prefixed. Avoid for new docs when the index can resolve the symbol. | @@ -53,7 +53,9 @@ Platform names use `PlatformContext.name`: `Angular`, `React`, {/* Let the generated index find package, kind, and exact symbol name. */} -{/* Member anchors are resolved from the generated member map. */} +{/* Member anchors are resolved from the generated member map. With no + `label`, the display text defaults to the member name, cased per platform: + `rowSelection` for WebComponents/React/Angular, `RowSelection` for Blazor. */} {/* Use pkg only when the symbol name is ambiguous across packages. */}