Skip to content
Merged
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
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