diff --git a/.changeset/stamped-versions.md b/.changeset/stamped-versions.md new file mode 100644 index 00000000..8019a2cd --- /dev/null +++ b/.changeset/stamped-versions.md @@ -0,0 +1,7 @@ +--- +'@nasa-hds/core': patch +--- + +Stamp the HDS and USWDS versions into the compiled CSS + +Every bundle now opens with a banner naming its version and the USWDS version it was built against, and `hds.min.css` exposes `--hds-version` and `--hds-uswds-version` for runtime reads. These are diagnostics for copied-`dist/` deployments that keep no other record of what is installed; both values belong in any bug report. See [Installation](?path=/docs/overview-installation--docs) for how to read them. diff --git a/.config/postcss-hds-stamp.mjs b/.config/postcss-hds-stamp.mjs new file mode 100644 index 00000000..186d79aa --- /dev/null +++ b/.config/postcss-hds-stamp.mjs @@ -0,0 +1,66 @@ +/** + * HDS Version Stamp — PostCSS plugin + * + * Stamps the HDS + USWDS versions into every compiled bundle: a `/*!` banner + * on all bundles, plus --hds-version / --hds-uswds-version on :root in + * hds.min.css only (a stale copy of an optional bundle must not win the + * cascade and misreport the version). + * + * Runs last in the postcss chain so the banner survives comment-discarding + * and minification. Versions are read at build time, so the stamp tracks the + * changesets bump with nothing to regenerate. + */ + +import fs from 'node:fs'; + +const read = (path) => JSON.parse(fs.readFileSync(path, 'utf8')); + +const HDS_VERSION = read('./package.json').version; +const USWDS_VERSION = read('./node_modules/@uswds/uswds/package.json').version; + +/** Bundles that carry the custom properties, keyed by output filename. */ +const STAMPS_PROPERTIES = new Set(['hds.min.css', 'hds.css']); + +export default function hdsStamp() { + return { + postcssPlugin: 'postcss-hds-stamp', + + OnceExit(root, { result, Comment, Rule, Declaration, AtRule }) { + const file = result.opts.to ? result.opts.to.split(/[\\/]/).pop() : ''; + + // We compile USWDS from source, so its banner ships the literal + // `uswds @version` placeholder that USWDS substitutes in its own build. + root.walkComments((comment) => { + if (comment.text.includes('uswds @version')) { + comment.text = comment.text.replace('uswds @version', `uswds v${USWDS_VERSION}`); + } + }); + + if (STAMPS_PROPERTIES.has(file)) { + const rule = new Rule({ selector: ':root' }); + // Unquoted: `getPropertyValue('--hds-version')` then reads back as + // `0.9.0` rather than `'0.9.0'`, which is what a support request or a + // console one-liner actually wants. + rule.append(new Declaration({ prop: '--hds-version', value: HDS_VERSION })); + rule.append(new Declaration({ prop: '--hds-uswds-version', value: USWDS_VERSION })); + + // hds-base is already declared in every bundle's layer order; + // layers merge, so appending here needs no other coordination. + const layer = new AtRule({ name: 'layer', params: 'hds-base' }); + layer.append(rule); + root.append(layer); + } + + const banner = new Comment({ + text: `! @nasa-hds/core v${HDS_VERSION}${file ? ` — ${file}` : ''} | uswds v${USWDS_VERSION} | CC0 1.0 | https://github.com/nasa/hds-core `, + }); + banner.raws.left = ''; + banner.raws.right = ''; + + // After @charset, which must stay first. + const charset = root.first?.name === 'charset' ? root.first : null; + if (charset) charset.after(banner); + else root.prepend(banner); + }, + }; +} diff --git a/package.json b/package.json index 210c7939..123036e9 100644 --- a/package.json +++ b/package.json @@ -23,12 +23,12 @@ "./scss": "./src/scss/hds.scss", "./scss/uswds": "./src/scss/hds-uswds.scss", "./scss/dataviz": "./src/scss/hds-dataviz.scss", - "./assets": "./dist/assets/" + "./js/uswds": "./dist/js/uswds.min.js", + "./assets/*": "./dist/assets/*" }, "files": [ "dist/", - "src/scss/", - "src/assets/" + "src/scss/" ], "scripts": { "sass:hds": "sass src/scss/hds.scss dist/css/hds.css --load-path=node_modules/@uswds/uswds/packages --load-path=src/scss --source-map --style=expanded --quiet-deps", diff --git a/postcss.config.mjs b/postcss.config.mjs index 83425a91..78330a93 100644 --- a/postcss.config.mjs +++ b/postcss.config.mjs @@ -2,10 +2,15 @@ import autoprefixer from 'autoprefixer'; import discardComments from 'postcss-discard-comments'; import cssnano from 'cssnano'; +import hdsStamp from './.config/postcss-hds-stamp.mjs'; + const plugins = [autoprefixer(), discardComments()]; if (process.env.MINIFY === 'true' || process.env.NODE_ENV === 'production') { plugins.push(cssnano({ preset: 'default' })); } +// Last: the version banner must outlive comment discarding and minification. +plugins.push(hdsStamp()); + export default { plugins }; diff --git a/public-api.snapshot.txt b/public-api.snapshot.txt index 1632317d..75cfa9d0 100644 --- a/public-api.snapshot.txt +++ b/public-api.snapshot.txt @@ -149,6 +149,8 @@ src/scss/hds-uswds.scss --hds-summary-border-radius --hds-summary-border-width --hds-table-border-width +--hds-uswds-version +--hds-version ## Custom Properties (hds-dataviz.min.css) --hds-dataviz-color-cat-1 diff --git a/stories/guides/NoBuildEnvironments.mdx b/stories/guides/NoBuildEnvironments.mdx index 0b9b0167..c767880d 100644 --- a/stories/guides/NoBuildEnvironments.mdx +++ b/stories/guides/NoBuildEnvironments.mdx @@ -10,7 +10,7 @@ Before using this guide, confirm your site is approved to remain standalone. See ## Add the stylesheet and scripts -Download the HDS Core distribution from GitHub or install via npm, then add these to your HTML: +First [get the package](?path=/docs/overview-installation--docs#get-the-package): download the dist zip or install via npm, and verify the download. Then add these to your HTML: ```html @@ -28,17 +28,13 @@ Download the HDS Core distribution from GitHub or install via npm, then add thes USWDS 3.x is written in vanilla JavaScript and does not conflict with jQuery. If your legacy site depends on older versions of jQuery, the USWDS scripts run safely alongside it. -### Verify the download before you copy it onto your server +A copied `dist/` keeps no record of what you installed, so the stylesheet carries its own version. Read it at runtime to confirm what is deployed: -npm verifies package integrity for you. If you download the dist zip from the [Releases page](https://github.com/nasa/hds-core/releases) instead, that check is yours to run. GitHub displays a SHA-256 digest under the zip asset on the release, and the release notes repeat the same digest under "Verify your download". - -Hash your download and confirm it matches the digest on the release before extracting: - -```sh -sha256sum hds-core-*-dist.zip +```js +getComputedStyle(document.documentElement).getPropertyValue('--hds-version').trim(); // 0.9.0 ``` -On macOS, use `shasum -a 256` instead. If the two digests differ, the file was corrupted or tampered with in transit. Do not deploy it: re-download, and if it still fails, [open an issue](https://github.com/nasa/hds-core/issues). +See [Installation](?path=/docs/overview-installation--docs#which-version-am-i-running) for the full version and provenance details. ## Use HDS tokens in your existing CSS @@ -135,7 +131,7 @@ Fixed-width containers break on mobile and fail responsive layout requirements. ``` -> These grid and layout classes require loading `hds-uswds.min.css` alongside `hds.min.css`. This is a temporary migration step — as you modernize your markup, the goal is to move toward CSS Grid and Flexbox natively, which removes the need for utility classes entirely. +> These grid and layout classes are included in `hds.min.css`, so no extra file is needed. (The optional `hds-uswds.min.css` bundle adds spacing, color, and other utility classes like `.padding-2` or `.text-primary`, not grid.) Grid is a temporary migration step: as you modernize your markup, the goal is to move toward CSS Grid and Flexbox natively, which removes the need for utility classes entirely. ### Semantics: fix inaccessible markup diff --git a/stories/guides/ReactSetup.mdx b/stories/guides/ReactSetup.mdx index 06edd238..60c78ce9 100644 --- a/stories/guides/ReactSetup.mdx +++ b/stories/guides/ReactSetup.mdx @@ -65,9 +65,9 @@ export default defineConfig({ viteStaticCopy({ targets: [ // HDS fonts (DM Mono, Inter) — lands at dist/assets/fonts/ - { src: 'node_modules/@nasa-hds/core/src/assets/fonts', dest: 'assets', rename: { stripBase: 5 } }, + { src: 'node_modules/@nasa-hds/core/dist/assets/fonts', dest: 'assets', rename: { stripBase: 5 } }, // HDS icon SVGs (accordion, table sort, external link, form error) - { src: 'node_modules/@nasa-hds/core/src/assets/img', dest: 'assets', rename: { stripBase: 5 } }, + { src: 'node_modules/@nasa-hds/core/dist/assets/img', dest: 'assets', rename: { stripBase: 5 } }, // Public Sans — from USWDS — lands at dist/assets/fonts/public-sans/ { src: 'node_modules/@uswds/uswds/dist/fonts/public-sans', dest: 'assets/fonts', rename: { stripBase: 5 } }, // USWDS images (checkboxes, radio indicators, etc.) @@ -79,7 +79,6 @@ export default defineConfig({ preprocessorOptions: { scss: { loadPaths: ['node_modules/@uswds/uswds/packages', 'node_modules/@nasa-hds/core/src/scss'], - loadPaths: ['node_modules/@uswds/uswds/packages', 'node_modules/@nasa-hds/core/src/scss'], }, }, }, diff --git a/stories/guides/SassConfiguration.mdx b/stories/guides/SassConfiguration.mdx index bcb5da85..ce56d4ae 100644 --- a/stories/guides/SassConfiguration.mdx +++ b/stories/guides/SassConfiguration.mdx @@ -4,159 +4,80 @@ import { Meta } from '@storybook/addon-docs/blocks'; # Sass Configuration -This guide covers advanced USWDS theme customization for projects using the Sass integration path. For basic Sass setup, see [Installation](?path=/docs/overview-installation--docs). +The Sass path lets you build your own components in the HDS design language. You get HDS design tokens, USWDS functions, and HDS mixins as compile-time values, so custom styles you write match HDS exactly. -## Customizing USWDS settings +The entry point is a single forward: -HDS Core configures USWDS with HDS values: colors, fonts, spacing, and component behavior. Many of these settings can be further customized in your project. Others are reserved by HDS Core and should not be overridden. +```scss +@forward '@nasa-hds/core/scss'; +``` -**USWDS Sass settings (`$theme-*` variables) cannot be overridden from consumer stylesheets.** HDS Core calls `@use 'uswds-core' with (...)` internally before your entry point runs. In Sass's module system, a module can only be configured the first time it loads. Attempting a second `@use 'uswds-core' with (...)` in your own Sass will throw a compile error. Do not add `@use 'uswds-core'` to your project stylesheets; see [Installation](?path=/docs/overview-installation--docs#common-mistakes) for why. +`@nasa-hds/core/scss` is a package export that resolves to HDS Core's Sass entry. It is the one string to use; do not reach into internal paths like `@nasa-hds/core/src/scss/hds`. You also configure two Sass load paths so the compiler can find HDS and USWDS: see [Installation](?path=/docs/overview-installation--docs#sass-setup) for the load-path setup and the full entry-point examples (utilities, dataviz). -## Global element styles +You do not reconfigure the HDS theme from Sass. The NASA visual identity is fixed on purpose (see [USWDS settings](#uswds-settings)), the same way the VA and CMS design systems fix theirs. What you customize is your own code, using the surface below. -By default, HDS Core does not style bare HTML elements (`

`, `

`, ``, ``, etc.). This prevents conflicts with existing styles in your project. Because USWDS settings are locked by HDS Core (see above), this default cannot be changed via Sass. +## What you can use -Use USWDS classes to activate styling on the elements you control: +With HDS Core forwarded, HDS variables, USWDS functions, and HDS mixins are available in your own stylesheets: -- `.usa-prose` wraps body content sections with full HDS typography (headings, paragraphs, lists, links) -- `.usa-link` applies link styling to individual anchors -- `.usa-button` applies button styling -- `.usa-intro` applies lead/intro paragraph styling +```scss +.my-component { + background-color: $hds-color-carbon-05; + color: $hds-color-carbon-90; + font-family: family('heading'); + font-size: size('heading', 'md'); + padding: units(3); -These class-based styles are always active and cover the same elements that global flags would affect. + &:focus-visible { + @include hds-focus-ring; + } +} +``` -## Settings you may need to adjust +- **HDS Sass variables** (`$hds-color-*`, `$hds-spacing-*`, `$hds-font-*`, and the rest) return exact HDS values. +- **USWDS functions** (`family()`, `size()`, `units()`, `color()`) work as documented in the [USWDS documentation](https://designsystem.digital.gov/design-tokens/). +- **HDS mixins** apply HDS patterns: `hds-focus-ring` (and `hds-focus-ring-inline`, `hds-focus-ring-size`), `hds-link-appearance`, `hds-link-hover`, `visually-hidden`, and `hds-type` (applies a type-ramp step to any element). +- **Two configuration flags** are yours to set at import time: `$hds-enable-dataviz-tokens` and `$hds-enable-auto-dark-mode`. -Most projects won't need to change anything — HDS Core configures USWDS with the correct values. These are the few settings that depend on your specific project setup. +`color()` returns USWDS system token values, which are close approximations of HDS Carbon colors but not exact matches. For example, USWDS `gray-90` is `#1b1b1b`, while HDS Carbon 90 is `#17171B`. For exact HDS values, use `$hds-color-*` variables or `var(--hds-color-*)` custom properties. -### Asset paths +Because your components are built on the shared HDS token surface rather than a private fork, they stay compatible with HDS and can be [contributed back](?path=/docs/overview-getting-started--docs) into HDS Core. -Adjust these if your build pipeline outputs assets to a different location than the HDS Core default. +## HDS utility classes -| Setting | HDS Default | When to change | -| ------------------- | ------------------- | ------------------------------------------------------------------------ | -| `$theme-image-path` | `'../assets/img'` | Your compiled CSS is not one directory above your `assets/img/` folder | -| `$theme-font-path` | `'../assets/fonts'` | Your compiled CSS is not one directory above your `assets/fonts/` folder | +HDS ships a few utility classes beyond USWDS: -### Fixed header offsets +| Class | Purpose | +| -------------------------- | ----------------------------------------------------------------------------------------------------------------- | +| `.hds-print-visible` | Show an element in print that is hidden on screen (expanded URLs, critical alerts). | +| `.hds-global-styles` | Opt-in wrapper that styles bare HTML elements inside it. See [Content element styling](#content-element-styling). | +| `.hds-global-styles-reset` | Reset boundary inside a `.hds-global-styles` or `.usa-prose` scope, returning descendants to unstyled markup. | -If your site has a fixed or sticky header, these prevent content from being hidden behind it. +The `visually-hidden` mixin provides screen-reader-only text from your own Sass. -| Setting | Default | What it controls | -| -------------------------------- | ---------- | --------------------------------------------------------------------------------------------------------------------------- | -| `$theme-in-page-nav-top` | `4` (32px) | Distance from the top of the viewport when the in-page navigation sidebar becomes sticky. Increase to clear a fixed header. | -| `$theme-table-sticky-top-offset` | `0px` | Offset for sticky table headers. Increase to clear a fixed header. | +All [USWDS utility classes](https://designsystem.digital.gov/utilities/) for layout, spacing, and typography work with HDS Core. USWDS color utilities (`.bg-*`, `.text-*`, `.border-*`) also work, but resolve to USWDS system token values, which approximate HDS colors rather than matching them exactly. For exact HDS colors, use `$hds-color-*` Sass variables or `var(--hds-color-*)` custom properties. -### Form input width +HDS also ships typography classes (`.hds-h1`–`.hds-h6`, `.hds-display-*`, `.hds-stat-*`, and more) and palette wrappers (`.hds-palette-*`). Those are documented where they are designed: see [Typography](?path=/docs/foundations-typography--docs) and [Color](?path=/docs/foundations-color--docs). -| Setting | Default | What it controls | -| ------------------------ | ------------- | -------------------------------------------------------------------------------------- | -| `$theme-input-max-width` | `"mobile-lg"` | Max width of text inputs and selects. Increase if your layout needs wider form fields. | +## Content element styling -### Compile output +By default, HDS Core does not style bare HTML elements (`

`, `

`, ``, `

`, etc.), so it never conflicts with existing styles in your project. Opt in where you want it by wrapping content in one of these scopes: -| Setting | HDS Default | What it controls | -| ------------------------------ | ----------- | -------------------------------------------------------------------------------------------------------- | -| `$utilities-use-important` | `false` | Whether utility classes use `!important`. Set to `true` if utilities conflict with your existing styles. | -| `$theme-show-compile-warnings` | `false` | Show Sass warnings from USWDS. Enable for debugging. | -| `$theme-show-notifications` | `false` | Show USWDS build notifications. Enable for debugging. | +- `.hds-global-styles` is the HDS-native wrapper. Bare elements inside it (headings, paragraphs, links, lists, blockquotes, code, figures, and tables) take HDS styling. +- `.usa-prose` is the USWDS-standard equivalent and applies the same styling. -## Reserved settings +Inside either scope, add `.hds-global-styles-reset` to an element to return it and its descendants to unstyled markup, for a region you want to control yourself. -HDS Core relies on these settings to implement the HDS visual language correctly. Overriding them will break the design system's intended appearance and behavior. +`.usa-link`, `.usa-button`, and `.usa-intro` style individual elements without a wrapper. -### Primary and secondary color families +## USWDS settings -HDS intentionally swaps the USWDS color assignments (NASA Red = primary, NASA Blue = secondary) to support the [wayfinding rule](?path=/docs/foundations-color--docs): red navigates away, blue stays on page. Changing any primary or secondary setting breaks button colors, link treatments, and the entire wayfinding system. +USWDS Sass settings (`$theme-*` variables) cannot be overridden from consumer stylesheets. HDS Core calls `@use 'uswds-core' with (...)` internally before your entry point runs, and in Sass's module system a module can only be configured the first time it loads. A second `@use 'uswds-core' with (...)` in your own Sass throws a compile error, so do not add `@use 'uswds-core'` to your project stylesheets. -- `$theme-color-primary-family`, `$theme-color-primary`, and all `primary-*` variants -- `$theme-color-secondary-family`, `$theme-color-secondary`, and all `secondary-*` variants +This is why `@use` and `@forward` order matters on the Sass path: forward HDS Core before any of your own Sass that touches USWDS, so HDS configures `uswds-core` first. (Compiled-CSS link order is separate and does not matter; HDS manages that with cascade layers.) -### Base color family +This seals the NASA visual identity: colors, fonts, the type scale, the grid, focus treatment, and component shapes are all set by HDS and are not consumer knobs. -These map the HDS Carbon scale to the closest USWDS gray tokens. USWDS components use these for backgrounds, borders, and text. Changing them shifts the entire neutral palette away from the Carbon scale. +You may be tempted to copy HDS Core's theme file into your project and edit it there. It compiles, but you then own a fork of every HDS setting: each release that changes a token, adds a component, or bumps USWDS drifts away from your copy silently, and you are no longer on HDS Core. If you need HDS itself to be different, [raise it with the HDS team](?path=/docs/overview-getting-started--docs): either it is a gap HDS should fill for everyone, or an intentional deviation that needs design sign-off. -- `$theme-color-base-family` and all `base-*` variants -- `$theme-color-base-ink` - -### Link color scheme - -HDS links use body text color (not brand color) for the text itself. The dotted underline and external arrow provide the visual affordance. These settings prevent bare `` tags from rendering in NASA Red after the primary/secondary swap. - -- `$theme-link-color`, `$theme-link-hover-color`, `$theme-link-active-color`, `$theme-link-visited-color` -- `$theme-link-reverse-color`, `$theme-link-reverse-hover-color`, `$theme-link-reverse-active-color` -- `$theme-body-background-color`, `$theme-text-color`, `$theme-text-reverse-color` - -### Focus ring - -HDS uses a palette-aware focus ring (1px dashed, adapts to each palette background). These base settings are overridden per-palette in CSS — changing them creates inconsistent focus indicators. - -- `$theme-focus-color`, `$theme-focus-offset`, `$theme-focus-style`, `$theme-focus-width` - -### Font families and roles - -HDS maps three specific fonts to USWDS family slots (Inter → `serif`, Public Sans → `sans`, DM Mono → `mono`) and assigns them to roles (heading, body, ui, code, alt). Changing any of these breaks the HDS type system. - -- `$theme-font-type-sans`, `$theme-font-type-serif`, `$theme-font-type-mono` -- `$theme-font-role-heading`, `$theme-font-role-body`, `$theme-font-role-ui`, `$theme-font-role-code`, `$theme-font-role-alt` -- `$theme-typeface-tokens`, `$theme-font-serif-custom-src`, `$theme-font-mono-custom-src` - -### Type scale and element sizing - -These map the HDS Core Proposal type scale to USWDS size tokens. Changing them misaligns heading sizes, body text, and display typography from the HDS spec. - -- `$theme-type-scale-3xs` through `$theme-type-scale-3xl` -- `$theme-h1-font-size` through `$theme-h6-font-size` -- `$theme-body-font-size`, `$theme-body-font-family`, `$theme-small-font-size`, `$theme-display-font-size` - -### Line heights and font weights - -These pull values directly from HDS design tokens. - -- `$theme-body-line-height`, `$theme-heading-line-height`, `$theme-lead-line-height`, `$theme-input-line-height` -- All `$theme-font-weight-*` settings - -### Grid, layout, and breakpoints - -HDS Core configures the grid system, breakpoints, column gaps, site margins, and container max widths to match the HDS spec. - -- `$theme-grid-container-max-width`, `$theme-header-max-width`, `$theme-footer-max-width`, `$theme-header-min-width` -- `$theme-site-margins-width`, `$theme-site-margins-mobile-width`, `$theme-site-margins-breakpoint` -- `$theme-column-gap-sm`, `$theme-column-gap-md`, `$theme-column-gap-lg`, `$theme-column-gap-mobile`, `$theme-column-gap-desktop` -- `$theme-utility-breakpoints` - -### Component border radii, stroke widths, and typography - -These are set from HDS design tokens and ensure consistent component appearance. - -- `$theme-button-border-radius`, `$theme-button-stroke-width`, `$theme-button-font-family` -- `$theme-card-border-radius`, `$theme-card-border-width` -- `$theme-checkbox-border-radius`, `$theme-input-tile-border-radius`, `$theme-input-tile-border-width` -- `$theme-input-select-border-width`, `$theme-input-state-border-width` -- `$theme-modal-border-radius` -- `$theme-pagination-button-border-radius`, `$theme-pagination-button-border-width`, `$theme-pagination-font-family` -- `$theme-summary-box-border-radius`, `$theme-summary-box-border-width` -- `$theme-form-font-family` -- `$theme-input-background-color` - -### State, accent, and table colors - -The state colors (error, warning, success, info, disabled, emergency), accent colors (cool, warm), and table theme tokens are set to reasonable values. Changing them may produce unexpected results in alerts, form validation, and data tables. - -- All `$theme-color-error-*`, `$theme-color-warning-*`, `$theme-color-success-*`, `$theme-color-info-*`, `$theme-color-disabled-*`, `$theme-color-emergency-*` -- All `$theme-color-accent-warm-*`, `$theme-color-accent-cool-*` -- All `$theme-table-*` (except `$theme-table-sticky-top-offset`, listed above as adjustable) - -### Everything else - -USWDS has [hundreds of settings](https://designsystem.digital.gov/documentation/settings/) for individual components. Settings not listed above are not configured by HDS Core. They use USWDS defaults, which generally work fine with HDS theming. If you need to fine-tune a specific USWDS component, consult the USWDS documentation and test thoroughly. - -## Utility classes - -HDS Core provides a small number of utility classes beyond what USWDS offers. - -| Class | Purpose | -| -------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------- | -| `.hds-print-visible` | Makes an element visible in print that is hidden on screen. Use for content that should only appear in printed output (e.g., expanded URLs, critical alerts). | - -All [USWDS utility classes](https://designsystem.digital.gov/utilities/) for layout, spacing, and typography work as expected with HDS Core. USWDS color utilities (`.bg-*`, `.text-*`, `.border-*`) also work, but use USWDS system token values which are close approximations of HDS colors — not exact matches. For exact HDS colors in custom styles, use `$hds-color-*` Sass variables or `var(--hds-color-*)` CSS custom properties. +For project-specific results, write your own CSS in the `site` cascade layer, which always wins over HDS defaults without `!important`, or use your own Sass variables. diff --git a/stories/guides/USWDS.mdx b/stories/guides/USWDS.mdx index fe9e5cba..fe926425 100644 --- a/stories/guides/USWDS.mdx +++ b/stories/guides/USWDS.mdx @@ -2,19 +2,15 @@ import { Meta } from '@storybook/addon-docs/blocks'; -# Adopting HDS Core on an Existing USWDS Site +# Existing USWDS Site -HDS Core adopts cleanly onto an existing USWDS 3.x site. Your existing markup should work unchanged, with no class renames or DOM restructuring required. Some markup additions and CSS review are needed to render correctly in HDS's visual identity. This guide walks through what to expect and what to adjust. - -## The adoption shape +HDS Core adopts onto an existing USWDS 3.x site. Your markup works unchanged: no class renames, no DOM restructuring. To render correctly in HDS's visual identity, you add some markup and review your custom CSS. Expect three layers of work, in order: -1. **Install**: Swap the stylesheet reference. Your site still renders, nothing crashes. -2. **Visual alignment**: Add HDS palette classes where your site uses USWDS dark or light context markup. Audit your custom CSS against HDS's cascade architecture. -3. **Brand compliance**: Review button intent, component variants, and any USWDS patterns HDS renders differently. - -A site that completes step 1 but skips steps 2 and 3 will render without breaking, but will not match the HDS design language. Full alignment requires all three. +1. **Install.** Swap the stylesheet reference. Your site still renders and nothing crashes. +2. **Visual alignment.** Add HDS palette classes where your site uses USWDS dark or light context markup, and check your custom CSS against HDS's cascade layers. +3. **Brand compliance.** Review button intent, component variants, and any USWDS patterns HDS renders differently. ## Install @@ -40,7 +36,7 @@ Swap the stylesheet reference. USWDS JavaScript is unmodified. ``` -Load order does not matter. HDS Core uses CSS cascade layers, so priority is determined by layer order, not file order. Not sure if your site uses utility classes? Search your templates for classes not prefixed with `usa-` or `hds-`. Classes like `.padding-2` or `.margin-top-3` are utilities. +The order you link these stylesheets does not matter. HDS Core uses CSS cascade layers, so priority is determined by layer order, not link order. Not sure if your site uses utility classes? Search your templates for classes not prefixed with `usa-` or `hds-`. Classes like `.padding-2` or `.margin-top-3` are utilities. For full setup options (Sass integration, load paths, tokens), see [Installation](?path=/docs/overview-installation--docs). @@ -76,13 +72,13 @@ To put one of them on a different surface, add a palette class to the same eleme ``` -Review every page for dark-mode markup and add palette classes accordingly. This is the most common source of visual issues during adoption. +Review every page for dark-mode markup and add palette classes accordingly. Missing palette classes are a common source of visual issues during adoption. ### Header, footer, banner, and identifier HDS Core does not theme the government banner, site header, footer, or identifier yet. They render as stock USWDS with HDS typography and color settings applied. Your markup keeps working, and there is nothing to change. -These four components pick their own background — white for the banner, header, and footer, black for the identifier — so HDS pins each one to the palette that matches. A `.hds-palette-dark` wrapper further up the page will not push white link text onto a white footer, and the identifier's required links stay white on its black bar. +These four components set their own background (white for the banner, header, and footer, black for the identifier), so HDS pins each one to the palette that matches. That way a `.hds-palette-dark` wrapper higher up the page does not push white link text onto a white footer, and the identifier's required links stay white on its black bar. To give one of them a different surface, put the palette class on the element itself: @@ -90,9 +86,9 @@ To give one of them a different surface, put the palette class on the element it
...
``` -A palette class on the element wins. A palette wrapper around it does not. +A palette class set directly on the element takes effect; a palette wrapper around it does not reach these four components. -Dedicated HDS header and footer components are the top priority for the first post-v1.0 release. See the [Roadmap](?path=/docs/overview-roadmap--docs). +Dedicated HDS header and footer components are planned for the first post-v1.0 release. See the [Roadmap](?path=/docs/overview-roadmap--docs). ### Custom CSS and the cascade layer contract @@ -106,10 +102,10 @@ The `site` layer is reserved for your custom CSS. Styles written inside `@layer #### The unlayered CSS trap -Custom CSS written outside any named layer silently beats every HDS rule, regardless of specificity. Unlayered rules always outrank layered rules in the CSS cascade. For existing USWDS sites with accumulated custom CSS, this has real consequences: +In the CSS cascade, any rule outside a named layer beats every rule inside one, whatever the specificity. So custom CSS you never put in a layer overrides HDS. On an existing USWDS site with years of accumulated custom CSS, that causes two problems: -- HDS may not render as designed. Your existing rules can override HDS styling in places you do not expect. -- Debugging cascade issues is harder because "unlayered beats layered" is counterintuitive if you are used to specificity-based overrides. +- HDS may not render as designed, because your existing rules override it in places you do not expect. +- Cascade issues are harder to debug, since "unlayered beats layered" runs opposite to the specificity rules most people reason with. #### Recommended adoption process for custom CSS @@ -149,7 +145,7 @@ Once installation and visual alignment are complete, review the following for br ### Button intent -This is the most significant component-level change. HDS uses a two-color wayfinding system: **red navigates away, blue stays on page.** +This is the component change most likely to affect your site. HDS uses a two-color wayfinding system: **red navigates away, blue stays on page.** | USWDS class | USWDS default | Under HDS | HDS meaning | | ------------------------ | -------------- | -------------------- | ----------------------------- | @@ -166,10 +162,10 @@ If your site already customizes USWDS via `@use "uswds-core" with (...)`, you wi ### The singleton rule -Sass modules can only be configured once. Whoever calls `@use "uswds-core" with (...)` first wins. Subsequent calls with different settings will error. When you adopt HDS Core: +A Sass module can only be configured once, by whichever file calls `@use "uswds-core" with (...)` first. A later call with different settings throws a compile error. When you adopt HDS Core: - **Pre-compiled CSS path:** No conflict. HDS Core's CSS is already compiled. Your Sass pipeline keeps its own `uswds-core` configuration for any custom styles you compile separately. -- **Sass path:** `@forward '@nasa-hds/core/src/scss/hds'` loads HDS Core's configuration first. Any `@use "uswds-core" with (...)` in your own files will fail if it tries to set different values. +- **Sass path:** `@forward '@nasa-hds/core/scss'` loads HDS Core's configuration first. Any `@use 'uswds-core' with (...)` in your own files throws a compile error, because a Sass module can only be configured once. Do not reconfigure `uswds-core` directly. HDS Core's configuration handles all USWDS theme settings. Use your own Sass variables or CSS custom properties for project-specific values that HDS does not expose. @@ -185,11 +181,11 @@ Review these against your current theme file. HDS Core overrides all of them: | Custom link colors | Changes to body-text color + dashed underline | Links no longer appear blue | | Custom border radii / input styles | Sets HDS-specific values | Form controls and buttons change shape | -If any of these are intentional deviations for your project, discuss with the HDS team. Some can be accommodated. Others are core to the HDS visual identity. +If any of these are intentional deviations your project needs to keep, raise them with the HDS team. Some can be accommodated; others are part of the HDS visual identity and will not change. -### What you can still customize +### Customizing beyond the HDS theme -Settings not reserved by HDS Core continue to work. See the [Sass Configuration guide](?path=/docs/guides-sass-configuration--docs) for the full list of adjustable vs. reserved settings. +Because HDS Core configures `uswds-core` first, you cannot change any `$theme-*` setting from your own Sass, including the ones USWDS docs present as project-level knobs. For project-specific styling, write CSS in the `site` cascade layer or use your own Sass variables and CSS custom properties. See the [Sass Configuration guide](?path=/docs/guides-sass-configuration--docs) for what HDS Core seals and what you can build with. ## Live preview diff --git a/stories/overview/GettingStarted.mdx b/stories/overview/GettingStarted.mdx index 75c719ba..55a23726 100644 --- a/stories/overview/GettingStarted.mdx +++ b/stories/overview/GettingStarted.mdx @@ -52,7 +52,7 @@ If your team built a compliant site by referencing NASA's Figma files or other d Two things to consider: - **Contribute back.** If you've built components or patterns that don't exist in HDS Core yet, we'd love to see them. Open a [Discussion](https://github.com/nasa/hds-core/discussions) or submit a pull request. -- **Consider adopting HDS Core tokens.** Design systems evolve. If your implementation is pinned to specific hex codes or spacing values, it won't stay current as NASA's visual language updates. Mapping your CSS to HDS Core tokens, even without changing your markup, keeps your site in sync automatically. The [Installation](?path=/docs/overview-installation--docs) page covers how different integration approaches work. +- **Consider adopting HDS Core tokens.** Design systems evolve. If your implementation is pinned to specific hex codes or spacing values, it won't stay current as NASA's visual language updates. Mapping your CSS to HDS Core tokens, even without changing your markup, means a version upgrade carries the new values through without your hunting down hardcoded ones. While HDS is pre-v1.0 you pin and upgrade deliberately (see [Installation](?path=/docs/overview-installation--docs)), so "current" means the version you chose, not an automatic push. ## Next steps diff --git a/stories/overview/Installation.mdx b/stories/overview/Installation.mdx index 273c084b..d8be0fe5 100644 --- a/stories/overview/Installation.mdx +++ b/stories/overview/Installation.mdx @@ -6,29 +6,92 @@ import { Meta } from '@storybook/addon-docs/blocks'; Technical setup for integrating HDS Core into your project. If you're evaluating whether HDS Core is the right fit for your site, start with [Getting Started](?path=/docs/overview-getting-started--docs). For visual requirements, see [Design Standards](?path=/docs/overview-design-standards--docs). +## Get the package + +Get HDS Core one of two ways. Use npm if your project uses it; otherwise download the release zip. Both give you the same files. + +### Option 1: Install via npm + +```sh +npm install --save-exact @nasa-hds/core +``` + +That is all the pre-compiled path needs: the CSS is self-contained and the USWDS scripts ship inside the package (`dist/js/`). npm verifies package integrity for you. Pin the exact version while HDS is pre-v1.0: minor releases can rename custom properties and change component styling, so you want upgrades to happen when you choose. + +`@uswds/uswds` is a peer dependency, which npm 7 and later installs for you automatically. The [Sass path](#sass-setup) compiles against it from source, so install it explicitly (`npm install --save-exact @nasa-hds/core @uswds/uswds`) when you want to pin its version yourself, or when your tooling does not auto-install peers (monorepos, `--legacy-peer-deps`, and some package managers). + +### Option 2: Download the dist zip + +Download from the [Releases page](https://github.com/nasa/hds-core/releases). You get the same `dist/` directory to copy onto your server. Because npm's integrity check does not apply, verify the download yourself before extracting: + +```sh +sha256sum hds-core-*-dist.zip +``` + +On macOS, use `shasum -a 256`. Confirm the result matches the SHA-256 digest shown under the zip asset on the release (the release notes repeat it under "Verify your download"). If the two differ, the file was corrupted or tampered with in transit. Do not deploy it: re-download, and if it still fails, [open an issue](https://github.com/nasa/hds-core/issues). + +### What's in the package + +``` +dist/ + css/ + hds.min.css # Required: all USWDS components + HDS theme + hds-uswds.min.css # Optional: USWDS utility classes (.padding-*, .text-*) + hds-dataviz.min.css # Optional: data visualization color palettes + js/ + uswds-init.min.js # Runs early in ; readies interactive components + uswds.min.js # Component behavior; loaded deferred (unmodified USWDS) + assets/ # fonts and images referenced by the CSS +src/ + scss/ # Sass source: tokens, mixins, theme config +``` + ## Choose your approach -| | Pre-compiled CSS | Sass (recommended) | -| ----------------- | ------------------------------------------------ | ---------------------------------------------------------------------- | -| **Setup** | One `` tag | Requires a Sass compiler and load path configuration | -| **Customization** | CSS custom properties only | Full access to USWDS settings, HDS Sass variables, and USWDS functions | -| **Custom code** | `var(--hds-color-*)`, `var(--hds-font-weight-*)` | `$hds-color-*`, `family()`, `size()`, `units()`, `color()` | -| **Upgrade path** | May need to switch to Sass later | Easiest to evolve as HDS Core adds features | +| | Pre-compiled CSS | Sass (recommended) | +| ----------------- | ------------------------------------------------ | ---------------------------------------------------- | +| **Setup** | One `` tag | Requires a Sass compiler and load path configuration | +| **Customization** | CSS custom properties only | HDS Sass variables, USWDS functions, and HDS mixins | +| **Custom code** | `var(--hds-color-*)`, `var(--hds-font-weight-*)` | `$hds-color-*`, `family()`, `size()`, `units()` | +| **Upgrade path** | May need to switch to Sass later | Easiest to evolve as HDS Core adds features | + +If you're evaluating HDS Core, working on a content site, or don't have a build pipeline, use [pre-compiled CSS](#pre-compiled-css). You can switch to [Sass](#sass-setup) later without changing your markup. + +### Assets + +Both approaches end up the same way: every HDS stylesheet resolves its fonts and icons with relative paths (`url('../assets/...')`), so the deployed `assets/` directory must sit one directory up from the stylesheet, as a sibling of the `css/` folder: -If you're evaluating HDS Core, working on a content site, or don't have a build pipeline, start with pre-compiled CSS. You can switch to Sass later without changing your markup. +``` +public/ +├── css/ +│ └── hds.min.css +└── assets/ + ├── fonts/ + └── img/ +``` -No build pipeline at all? See the [No-Build Environments](?path=/docs/guides-no-build-environments--docs) guide for CDN-based setup. +If the stylesheet cannot find `assets/` one directory up, fonts and icons will 404. Copy `assets/` whole rather than picking out individual files. The two approaches differ only in how the files get there: with pre-compiled CSS you copy them yourself; with Sass your build tool copies them (see each section below). ## Pre-compiled CSS +Adopting HDS on an existing CMS, static HTML, or legacy site? The [No-Build Environments](?path=/docs/guides-no-build-environments--docs) guide covers migrating existing markup and styles onto HDS incrementally. + ### New HDS site ```html - - + + + + + + + + ``` -`hds.min.css` is self-contained. It includes all USWDS components (themed and unthemed), HDS overrides, and all foundation styles (typography, grid, layout). No other CSS file is required. +Two scripts, loaded differently. `uswds-init.min.js` runs early in ``, before the page paints, so interactive components (accordions, modals, the mobile menu) do not flash in an un-initialized state. `uswds.min.js` carries the component behavior and loads `defer` at the end of ``. Both are the unmodified USWDS scripts. If your site has no interactive USWDS components, you can omit them. + +`hds.min.css` is self-contained. It includes all USWDS components (themed and unthemed), HDS overrides, and all foundation styles (typography, grid, layout). No other CSS file is required. Copy the `assets/` directory to sit beside your CSS (see [Assets](#assets)). ### Existing USWDS site @@ -44,7 +107,7 @@ Replace your current USWDS stylesheet with `hds.min.css`: ``` -Your site renders in the HDS visual identity with no markup changes. See the [Existing USWDS Site guide](?path=/docs/guides-existing-uswds-site-guidance--docs) for what to review after switching. +This diff shows only the stylesheet change; your existing USWDS script setup, including `uswds-init.min.js`, stays as-is. Your site renders in the HDS visual identity with no markup changes. See the [Existing USWDS Site guide](?path=/docs/guides-existing-uswds-site-guidance--docs) for what to review after switching. If your site uses [USWDS utility classes](https://designsystem.digital.gov/utilities/) (`.padding-2`, `.margin-top-3`, `.text-primary`, etc.), also load the optional utilities bundle: @@ -54,7 +117,7 @@ If your site uses [USWDS utility classes](https://designsystem.digital.gov/utili ``` -Load order does not matter. HDS Core uses CSS cascade layers to manage specificity, so priority is determined by layer order, not file order. +The order you link these stylesheets does not matter. HDS Core uses CSS cascade layers to manage specificity, so priority is determined by layer order, not link order. (This is about linking compiled CSS. On the Sass path, `@use` and `@forward` order does matter, because it governs configuration; see the [Sass Configuration guide](?path=/docs/guides-sass-configuration--docs#uswds-settings).) Not sure if your site uses utility classes? Search your templates for classes that are not prefixed with `usa-` or `hds-`. If you find classes like `.padding-2` or `.margin-top-3`, load the utilities bundle. See the [Existing USWDS Site guide](?path=/docs/guides-existing-uswds-site-guidance--docs) for a full migration checklist. @@ -68,32 +131,22 @@ For sites rendering charts or graphs, an optional bundle provides CSS custom pro This bundle can be loaded standalone without `hds.min.css`, making it suitable for embedded chart contexts (such as an iframe or a visualization-only page that inherits other styles from a CMS theme). -### Overriding HDS styles +### Which version am I running? -HDS Core reserves a `site` cascade layer for your own overrides. Wrapping your styles in this layer guarantees they always win over HDS defaults, without needing `!important`: +Every compiled bundle opens with a banner comment naming its own version and the USWDS version it was built against: ```css -@layer site { - .usa-button { - border-radius: 0; - } -} +/*! @nasa-hds/core v0.9.0 — hds.min.css | uswds v3.13.0 | CC0 1.0 | https://github.com/nasa/hds-core */ ``` -Any CSS you write outside a named layer also wins over `@layer site` by default. - -### Using HDS tokens in your CSS +`hds.min.css` also exposes both as custom properties, so a deployed page can report them without anyone opening the file: -HDS design tokens are available as CSS custom properties: - -```css -.my-element { - color: var(--hds-color-nasa-blue); - font-weight: var(--hds-font-weight-bold); -} +```js +getComputedStyle(document.documentElement).getPropertyValue('--hds-version').trim(); // 0.9.0 +getComputedStyle(document.documentElement).getPropertyValue('--hds-uswds-version').trim(); // 3.13.0 ``` -All `$hds-color-*` Sass variables are mirrored as `var(--hds-color-*)` custom properties on `:root`. +Include both in any bug report. They are the fastest way to tell a styling problem from a version mismatch, particularly for copied-file deployments, where nothing else on the server records what was installed. ## Sass setup @@ -104,7 +157,7 @@ Configure your Sass compiler with these load paths: - `node_modules/@uswds/uswds/packages` - `node_modules/@nasa-hds/core/src/scss` -Most build tools accept a `loadPaths` or `includePaths` array in their Sass configuration. +Most build tools accept a `loadPaths` or `includePaths` array in their Sass configuration. These are resolution roots for the compiler, not the thing you import: you forward the package export `@nasa-hds/core/scss` (see below), and the load paths let it and USWDS resolve. ### Entry point @@ -114,6 +167,8 @@ Most build tools accept a `loadPaths` or `includePaths` array in their Sass conf @forward 'my-project-styles'; ``` +`@forward` order matters: forward HDS Core before your own Sass that touches USWDS, so HDS configures `uswds-core` first. See the [Sass Configuration guide](?path=/docs/guides-sass-configuration--docs#uswds-settings) for why. + To include USWDS utility classes: ```scss @@ -128,37 +183,11 @@ To include USWDS utility classes: @forward '@nasa-hds/core/scss/dataviz'; ``` -### Vite: copy fonts and icons - -HDS Core's Sass source references fonts and icons with relative paths (`url('../assets/fonts/...')`). Vite cannot resolve these at compile time — you must copy the assets to the expected output location using `vite-plugin-static-copy`. See the [React guide](?path=/docs/guides-react-guidance--docs#sass-setup) for the full `vite.config.js` example. The same configuration applies to non-React Vite projects. - -### Using HDS tokens in Sass - -With HDS Core loaded, HDS Sass variables and USWDS functions are available in your own stylesheets: - -```scss -.my-component { - background-color: $hds-color-carbon-05; - color: $hds-color-carbon-90; - font-family: family('heading'); - font-size: size('heading', 'md'); - padding: units(3); -} -``` - -All HDS brand and Carbon colors are available as `$hds-color-*` Sass variables returning exact HDS hex values. - -USWDS functions (`family()`, `size()`, `units()`, `color()`) work as documented in the [USWDS documentation](https://designsystem.digital.gov/design-tokens/). - -Note: `color()` returns USWDS system token values, which are close approximations of HDS Carbon colors but not exact matches. For example, USWDS `gray-90` is `#1b1b1b`, while HDS Carbon 90 is `#17171B`. For exact HDS values, use `$hds-color-*` variables or `var(--hds-color-*)` custom properties. - -For USWDS theme customization, global element style flags, and advanced configuration, see the [Sass Configuration guide](?path=/docs/guides-sass-configuration--docs). - -## Common mistakes +### Copy the assets -**Don't `@use "uswds-core"` directly in your project stylesheets.** HDS Core configures USWDS before anything else loads it. Importing `uswds-core` yourself loads it without HDS configuration and breaks the theme. HDS Sass variables and USWDS functions are available automatically after forwarding HDS Core. +A Sass compiler does not copy fonts and icons, so your build tool must place the `assets/` directory beside your compiled CSS (see [Assets](#assets)). How you do that depends on your toolchain. For Vite, the [React guide](?path=/docs/guides-react-guidance--docs#sass-setup) shows a `vite-plugin-static-copy` configuration that applies to any Vite project; other bundlers have their own asset-copy step. -**Bare HTML elements are not styled by default.** If your headings, paragraphs, or links are not picking up HDS styles, add USWDS classes like `.usa-prose`, `.usa-link`, and `.usa-button`. Sass users can enable global element styling in the [Sass Configuration guide](?path=/docs/guides-sass-configuration--docs). +Once HDS Core is compiling, see the [Sass Configuration guide](?path=/docs/guides-sass-configuration--docs) for what you can build with HDS tokens, functions, and mixins, and what the theme seals. ## Framework-specific guides