Skip to content
Merged
Show file tree
Hide file tree
Changes from 11 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
44 changes: 34 additions & 10 deletions .storybook/preview-head.html
Original file line number Diff line number Diff line change
Expand Up @@ -5,29 +5,53 @@
<!-- Storybook default: `padding: 1rem` on `.sb-show-main.sb-main-padded` (base-preview-head.html).
- Main canvas: CFPB 15px ($space-sm).
- Nested "All viewports" (`?responsivePreview=off`): body padding 0; `#storybook-root` uses
vertical inset for focus plus 3px horizontal inset each side (6px narrower than the iframe
width when you measure `#storybook-root` children). Full-bleed stories pass
`sbNestedCanvasPadding=flush` (via `parameters.sbNestedCanvasPadding` in preview.js) for
zero inset instead. -->
vertical inset for focus plus small horizontal inset so outlines are not clipped at edges.
Full-bleed stories pass `sbNestedCanvasPadding=flush` (via `parameters.sbNestedCanvasPadding`
in preview.js) to use zero inset instead.
SecondaryNav: cfgov negative h-margins are overridden in nested mode. Default root uses
horizontal padding so :focus-visible rings are not clipped; the nav bleeds by the same
amount so the bar still spans the full iframe. The mobile header uses a negative
outline-offset so the dotted focus ring sits slightly inside the tap target. -->
<script>
(function applyCfpbStorybookCanvasPadding() {
var style = document.createElement('style');
var params = new URLSearchParams(window.location.search);
if (params.get('responsivePreview') === 'off') {
var rootInset =
params.get('sbNestedCanvasPadding') === 'flush'
? 'padding: 0 !important;'
: 'padding: 10px 3px !important;';
var flush = params.get('sbNestedCanvasPadding') === 'flush';
var hPadPx = 6;
var rootInset = flush
? 'padding: 0 !important;'
: 'padding: 10px ' + hPadPx + 'px !important;';
var bleedPx = hPadPx * 2;
var secondaryNavBox = flush
? 'margin-left: 0 !important; margin-right: 0 !important; width: auto; max-width: none; box-sizing: border-box;'
: 'margin-left: -' +
hPadPx +
'px !important; margin-right: -' +
hPadPx +
'px !important; width: calc(100% + ' +
bleedPx +
'px) !important; max-width: none !important; box-sizing: border-box !important;';
style.textContent =
'.sb-show-main.sb-main-padded { padding: 0 !important; }' +
'body.sb-show-main.sb-main-padded #storybook-root, body.sb-show-main.sb-main-centered #storybook-root { ' +
rootInset +
' box-sizing: border-box !important; }';
' box-sizing: border-box !important; overflow-x: visible !important; }' +
'body.sb-show-main.sb-main-padded #storybook-root .o-secondary-nav,' +
'body.sb-show-main.sb-main-centered #storybook-root .o-secondary-nav { ' +
secondaryNavBox +
' }' +
'body.sb-show-main.sb-main-padded #storybook-root .o-secondary-nav__header,' +
'body.sb-show-main.sb-main-centered #storybook-root .o-secondary-nav__header { min-width: 0; }' +
'body.sb-show-main.sb-main-padded #storybook-root .o-secondary-nav__label,' +
'body.sb-show-main.sb-main-centered #storybook-root .o-secondary-nav__label { min-width: 0; }' +
'body.sb-show-main.sb-main-padded #storybook-root .o-secondary-nav__header:focus-visible,' +
'body.sb-show-main.sb-main-centered #storybook-root .o-secondary-nav__header:focus-visible { position: relative; z-index: 1; outline-offset: -3px; }';
} else {
style.textContent =
'.sb-show-main.sb-main-padded { padding: 30px; }' +
'.sb-show-main.sb-main-centered #storybook-root { padding: 15px; }';
}
document.head.appendChild(style);
})();
</script>
</script>
11 changes: 9 additions & 2 deletions .storybook/preview.js
Original file line number Diff line number Diff line change
Expand Up @@ -200,7 +200,12 @@ const ResponsivePreviewFrame = ({ previewSrc, viewport }) => {
*
* @param {{ context: import('storybook/internal/types').StoryContext, nestedCanvasPaddingMode: 'focus' | 'flush', args: Record<string, unknown>, globals: Record<string, unknown> }} props
*/
const AllViewportsPreviews = ({ context, nestedCanvasPaddingMode, args, globals }) => {
const AllViewportsPreviews = ({
context,
nestedCanvasPaddingMode,
args,
globals,
}) => {
const argsParam = buildNestedQueryParam(context.initialArgs, args);
const globalsParam = buildNestedQueryParam(context.initialGlobals, globals);
const previewSrc = getPreviewSource(context.id, nestedCanvasPaddingMode, {
Expand Down Expand Up @@ -258,7 +263,9 @@ const renderResponsivePreviews = (Story, context) => {
return React.createElement(Story);
}

const nestedCanvasPaddingMode = getNestedCanvasPaddingMode(context.parameters);
const nestedCanvasPaddingMode = getNestedCanvasPaddingMode(
context.parameters,
);

return React.createElement(AllViewportsPreviews, {
context,
Expand Down
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
28 changes: 14 additions & 14 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,7 @@
},
"devDependencies": {
"@cfpb/browserslist-config": "^0.0.6",
"@cfpb/cfpb-design-system": "5.3.3",
"@cfpb/cfpb-design-system": "5.4.0",
"@chromatic-com/storybook": "^5.2.1",
"@eslint/js": "^10.0.1",
"@fontsource-variable/source-sans-3": "5.2.9",
Expand All @@ -71,23 +71,23 @@
"@testing-library/react": "^16.3.2",
"@testing-library/user-event": "^14.6.1",
"@types/css-mediaquery": "0.1.4",
"@types/node": "^25.8.0",
"@types/react": "^19.2.14",
"@types/node": "^25.9.1",
"@types/react": "^19.2.15",
"@types/react-dom": "^19.2.3",
"@types/testing-library__jest-dom": "6.0.0",
"@typescript-eslint/eslint-plugin": "8.59.3",
"@typescript-eslint/parser": "8.59.3",
"@vitejs/plugin-react": "^6.0.1",
"@vitest/browser-playwright": "4.1.6",
"@vitest/coverage-istanbul": "^4.1.6",
"@typescript-eslint/eslint-plugin": "8.59.4",
"@typescript-eslint/parser": "8.59.4",
"@vitejs/plugin-react": "^6.0.2",
"@vitest/browser-playwright": "4.1.7",
"@vitest/coverage-istanbul": "^4.1.7",
"astring": "^1.9.0",
"autoprefixer": "10.5.0",
"chromatic": "^16.10.0",
"chromatic": "^16.10.1",
"classnames": "^2.5.1",
"commitizen": "4.3.1",
"css-mediaquery": "0.1.2",
"cz-conventional-changelog": "3.3.0",
"eslint": "10.3.0",
"eslint": "10.4.0",
"eslint-config-prettier": "10.1.8",
"eslint-import-resolver-typescript": "^4.4.4",
"eslint-plugin-import": "2.32.0",
Expand All @@ -105,7 +105,7 @@
"lit": "^3.3.3",
"npm-run-all": "4.1.5",
"playwright": "^1.60.0",
"postcss": "8.5.14",
"postcss": "8.5.15",
"prettier": "3.8.3",
"react": "19.2.6",
"react-dom": "19.2.6",
Expand All @@ -116,16 +116,16 @@
"storybook": "^10.4.0",
"storybook-addon-tag-badges": "^3.1.0",
"storybook-font-inspector": "^1.1.7",
"stylelint": "^17.11.1",
"stylelint": "^17.12.0",
"stylelint-config-standard-scss": "^17.0.0",
"typescript": "^6.0.3",
"typescript-eslint": "^8.59.3",
"typescript-eslint": "^8.59.4",
"vite": "^8.0.13",
"vite-plugin-dts": "^4.5.4",
"vite-plugin-pwa": "^1.3.0",
"vite-plugin-svgr": "^5.2.0",
"vite-plugin-turbosnap": "^1.0.3",
"vitest": "^4.1.6"
"vitest": "^4.1.7"
},
"resolutions": {
"braces": "3.0.3",
Expand Down
4 changes: 3 additions & 1 deletion src/assets/styles/_shared.scss
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,9 @@
*/

/**
* Source Sans 3 is loaded via @fontsource in app / Storybook preview entrypoints.
* Source Sans 3 is loaded via `@fontsource-variable/source-sans-3` in **`src/index.ts`** (apps)
* and **`.storybook/preview.js`** (Storybook, including nested “All viewports” iframes) before
* `_shared.scss` so `@font-face` is always registered.
*
* DS `custom-props` sets `--font-stack-branded: initial`, so `var(--font-stack)` falls back to
* `system-ui`. Other DS chunks can repeat that `:root` block when code-split; in dev the last
Expand Down
14 changes: 9 additions & 5 deletions src/components/Hero/hero.stories.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -10,9 +10,11 @@ const meta: Meta<typeof Hero> = {
docs: {
description: {
component: `
Heroes are a primary focal point on landing and sublanding pages. They introduce a collection of pages by combining a brief description of the goals of that section along with a visually impactful graphic. To introduce lower-level pages, use the [text introduction](https://cfpb.github.io/design-system/patterns/text-introductions) instead.

This component supports illustration, photograph (overlay), and knockout variants only — not the DS jumbo or 50/50 patterns.
Heroes are a primary focal point on landing and sublanding pages. They
introduce a collection of pages by combining a brief description of the goals
of that section along with a visually impactful graphic. To introduce
lower-level pages, use the
[text introduction](https://cfpb.github.io/design-system/patterns/text-introductions) instead.

Source: https://cfpb.github.io/design-system/patterns/heroes
`,
Expand All @@ -26,8 +28,9 @@ export default meta;
type Story = StoryObj<typeof meta>;

export const WithIllustration: Story = {
name: 'With illustration',
args: {
heading: '41 chars max for a one-line heading',
heading: '41 characters max for a one-line heading',
image:
'https://cfpb.github.io/design-system/images/uploads/hero_illustration_example_keys.png',
subheading:
Expand All @@ -37,6 +40,7 @@ export const WithIllustration: Story = {
};

export const WithPhotograph: Story = {
name: 'With photograph',
args: {
...WithIllustration.args,
imageIsPhoto: true,
Expand All @@ -49,7 +53,7 @@ export const WithKnockoutText: Story = {
name: 'With knockout text',
args: {
...WithIllustration.args,
heading: 'Max of 41 chars for a one-line heading',
heading: '41 characters max for a one-line heading',
subheading:
'This text has a recommended count of 165-186 characters (three lines at 1230px) following a one-line heading and 108-124 characters (two lines at 1230px) following a two-line heading.',
backgroundColor: '#207676',
Expand Down
7 changes: 7 additions & 0 deletions src/components/Hero/hero.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,13 @@ interface HeroProperties extends HTMLAttributes<HTMLDivElement> {

/**
* https://cfpb.github.io/design-system/patterns/heroes
*
* The Jumbo and 50/50 hero variants, included in the CFPB Design System,
* and used on the CF.gov homepage are not included by this component.
*
* The implementation of the hero on https://www.consumerfinance.gov/es/
* uses a combination of Jumbo and 50/50 hero variants including some tweaks in
* wagtail.
*/
export default function Hero({
backgroundColor,
Expand Down
Loading
Loading