From b89427fa4cc2a318c437124642418d63b8f68259 Mon Sep 17 00:00:00 2001 From: Cory Rylan Date: Sun, 17 May 2026 21:30:33 -0500 Subject: [PATCH 1/2] chore(docs): add media docs support - Added '@nvidia-elements/media' to the configuration and package.json. - Updated Eleventy configuration to include public component documentation for media. - Enhanced example URL generation to support media components. - Refactored coverage calculation logic in API template for better clarity. - Updated pnpm lockfile to reflect new dependencies and versions. Signed-off-by: Cory Rylan --- knip.config.js | 1 + pnpm-lock.yaml | 3 +++ projects/internals/eslint/README.md | 1 + projects/site/eleventy.config.js | 3 ++- projects/site/package.json | 7 ++++++ projects/site/src/_11ty/layouts/docs.11ty.js | 1 + projects/site/src/_11ty/templates/api.js | 22 ++++++++++++++----- .../src/docs/elements/_tabs/examples.11ty.js | 3 ++- .../starters/eleventy-ssr/src/index.11ty.js | 8 +++++-- 9 files changed, 40 insertions(+), 9 deletions(-) diff --git a/knip.config.js b/knip.config.js index 4a8765e4fd..3e1f8984d8 100644 --- a/knip.config.js +++ b/knip.config.js @@ -24,6 +24,7 @@ export default { '@nvidia-elements/forms', '@nvidia-elements/lint', '@nvidia-elements/markdown', + '@nvidia-elements/media', '@nvidia-elements/styles', '@semantic-release/commit-analyzer', '@semantic-release/github', diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index ee1808b554..efcaf83656 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -1220,6 +1220,9 @@ importers: '@nvidia-elements/markdown': specifier: workspace:* version: link:../markdown + '@nvidia-elements/media': + specifier: workspace:* + version: link:../media '@nvidia-elements/monaco': specifier: workspace:* version: link:../monaco diff --git a/projects/internals/eslint/README.md b/projects/internals/eslint/README.md index 2f25b969ed..e862d2e214 100644 --- a/projects/internals/eslint/README.md +++ b/projects/internals/eslint/README.md @@ -74,6 +74,7 @@ Applied to `src/**/*.ts`, `src/**/*.tsx`, test files, and `*.examples.ts`. **Source hygiene** - **`no-dead-code`**. Flags commented-out imports, exports, declarations, control-flow, and test blocks. The project currently sets this to `warn` during cleanup. +- **`no-deep-class-inheritance`**. Limits class inheritance chains to two superclass hops by default, stopping at configured `allowedRoots` such as `HTMLElement` and `LitElement`. - **`require-spdx-header`**. Every source file must start with the two-line SPDX header (`SPDX-FileCopyrightText` copyright + `SPDX-License-Identifier: Apache-2.0`). The rule accepts any 4-digit year; auto-fix preserves an existing year and falls back to the current year only when inserting a header from scratch. ### Example rules (plugin `local-typescript`, files `**/*.examples.ts`) diff --git a/projects/site/eleventy.config.js b/projects/site/eleventy.config.js index d0f2282cfb..ad65bb7062 100644 --- a/projects/site/eleventy.config.js +++ b/projects/site/eleventy.config.js @@ -222,7 +222,7 @@ export default function (eleventyConfig) { * - Access the collection data in templates and layouts * - Sort and filter content based on frontmatter or other criteria * - * This collection includes all markdown files in src/docs/elements/, making component docs easily accessible throughout the site build process. + * This collection includes public component docs, making component metadata accessible throughout the site build process. * * Used by `../src/docs/elements/_tabs/api.11ty.js` to generate the API documentation page for each component. */ @@ -233,6 +233,7 @@ export default function (eleventyConfig) { 'src/docs/elements/data-grid/index.md', 'src/docs/code/*.md', 'src/docs/monaco/*.md', + 'src/docs/media/*.md', 'src/docs/markdown/index.md' ]); }); diff --git a/projects/site/package.json b/projects/site/package.json index 2a2b325ceb..d6a980b99d 100644 --- a/projects/site/package.json +++ b/projects/site/package.json @@ -88,6 +88,8 @@ "../forms/dist/**/*.examples.json", "../markdown/dist/**/*.js", "../markdown/dist/**/*.examples.json", + "../media/dist/**/*.js", + "../media/dist/**/*.examples.json", "../monaco/dist/**/*.js", "../monaco/dist/**/*.examples.json", "../internals/metadata/static/**", @@ -121,6 +123,10 @@ "script": "../markdown:build", "cascade": false }, + { + "script": "../media:build", + "cascade": false + }, { "script": "../monaco:build", "cascade": false @@ -244,6 +250,7 @@ "@nvidia-elements/forms": "workspace:*", "@nvidia-elements/lint": "workspace:*", "@nvidia-elements/markdown": "workspace:*", + "@nvidia-elements/media": "workspace:*", "@nvidia-elements/core": "workspace:*", "@nvidia-elements/monaco": "workspace:*", "@nvidia-elements/styles": "workspace:*", diff --git a/projects/site/src/_11ty/layouts/docs.11ty.js b/projects/site/src/_11ty/layouts/docs.11ty.js index fe2d38a00e..2af2646f9b 100644 --- a/projects/site/src/_11ty/layouts/docs.11ty.js +++ b/projects/site/src/_11ty/layouts/docs.11ty.js @@ -36,6 +36,7 @@ function getSection(url) { if (section === 'integrations') return 'integrations'; if (section === 'foundations') return 'foundations'; if (section === 'patterns') return 'patterns'; + if (section === 'media') return 'elements'; if (section === 'code' || section === 'monaco' || section === 'markdown') return 'code'; if (section === 'labs') return 'labs'; if (section === 'internal' || section === 'api-design') return 'internal'; diff --git a/projects/site/src/_11ty/templates/api.js b/projects/site/src/_11ty/templates/api.js index f506f4f30f..13b95f93f9 100644 --- a/projects/site/src/_11ty/templates/api.js +++ b/projects/site/src/_11ty/templates/api.js @@ -58,8 +58,7 @@ export function elementSummary(tag) { const element = elements.find(d => d.name === tag); const testReports = Object.values(tests.projects); const unitTestResults = testReports.flatMap(report => report.coverage.testResults); - const coverageTotal = - unitTestResults.find(result => result.file?.includes(tag.replace('nve-', '')))?.branches.pct ?? 0; + const coverageTotal = getElementCoverageTotal(tag, unitTestResults); const lighthouseResults = testReports .flatMap(report => report.lighthouse) .flatMap(result => result.testResults) @@ -93,6 +92,18 @@ export function elementSummary(tag) { `; } +function getElementCoverageTotal(tag, unitTestResults) { + const elementName = tag.replace('nve-', ''); + const implementationPath = `${elementName}/${elementName}.ts`; + const exactResult = unitTestResults.find(result => result.file === implementationPath); + const fileNameResult = unitTestResults.find(result => result.file?.endsWith(`/${elementName}.ts`)); + const broadResult = unitTestResults.find( + result => result.file?.includes(elementName) && !result.file.endsWith('/define.ts') + ); + + return (exactResult ?? fileNameResult ?? broadResult)?.branches.pct; +} + /** * Generates the component support buttons section for a given custom element tag. * @param {string} tag - The component tag name @@ -192,15 +203,16 @@ export function badgeStatus(status, container = '', content = '') { */ export function badgeCoverage(value, container = '', content = '') { let status = 'unknown'; - let formattedValue = value + const hasCoverage = Number.isFinite(value); + const formattedValue = hasCoverage ? new Intl.NumberFormat('default', { style: 'percent', minimumFractionDigits: 2, maximumFractionDigits: 2 }).format(value / 100) - : null; + : 'unknown'; - if (value !== undefined) { + if (hasCoverage) { if (value >= 90) { status = 'success'; } else if (value >= 70) { diff --git a/projects/site/src/docs/elements/_tabs/examples.11ty.js b/projects/site/src/docs/elements/_tabs/examples.11ty.js index be1feee827..46aa74bf50 100644 --- a/projects/site/src/docs/elements/_tabs/examples.11ty.js +++ b/projects/site/src/docs/elements/_tabs/examples.11ty.js @@ -26,12 +26,13 @@ export const data = { eleventyComputed: { noindex: data => data.component.data.hideExamplesTab || !data.component.data.tag }, - // Generate URLs in the format /docs/elements/{component-name}/examples/ or /docs/code/{component-name}/examples/ or /docs/monaco/{component-name}/examples/ + // Generate URLs in the format /docs/elements/{component-name}/examples/ or package-specific component docs paths. permalink: data => { const filePath = data.component.filePathStem; let dir = 'elements'; if (filePath.includes('/code/')) dir = 'code'; else if (filePath.includes('/monaco/')) dir = 'monaco'; + else if (filePath.includes('/media/')) dir = 'media'; else if (filePath.includes('/markdown/')) dir = ''; return `/docs/${dir}/${data.component.fileSlug}/examples/`; } diff --git a/projects/starters/eleventy-ssr/src/index.11ty.js b/projects/starters/eleventy-ssr/src/index.11ty.js index fa4c7de8f0..b04a565921 100644 --- a/projects/starters/eleventy-ssr/src/index.11ty.js +++ b/projects/starters/eleventy-ssr/src/index.11ty.js @@ -2,6 +2,9 @@ import { ApiService, ExamplesService } from '@internals/metadata'; +const ssrPackageNames = ['@nvidia-elements/code', '@nvidia-elements/core', '@nvidia-elements/media']; +const hasSsrEntrypoint = entrypoint => ssrPackageNames.some(packageName => entrypoint?.startsWith(`${packageName}/`)); + const elements = (await ApiService.getData()).data.elements; const examples = (await ExamplesService.getData()) .filter( @@ -14,10 +17,11 @@ const examples = (await ExamplesService.getData()) ) .map(example => { const element = elements.find(e => e.name === example.element && !e.manifest?.deprecated); - return element + const entrypoint = element?.manifest?.metadata?.entrypoint; + return element && hasSsrEntrypoint(entrypoint) ? { name: example.element, - entrypoint: element?.manifest?.metadata?.entrypoint, + entrypoint, template: example.template .replaceAll('