@deriv-com/dds-marketing 1.0.2 → 1.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.llm/components/awards.md +209 -0
- package/.llm/components/background.md +89 -40
- package/.llm/components/bottomsheet.md +5 -0
- package/.llm/components/comparisoncards.md +257 -0
- package/.llm/components/comparisontable.md +231 -0
- package/.llm/components/ctabanner.md +9 -12
- package/.llm/components/ctabannerslider.md +15 -2
- package/.llm/components/datatable.md +273 -0
- package/.llm/components/downloadbanner.md +283 -0
- package/.llm/components/featurecards.md +41 -3
- package/.llm/components/featurecardscarousel.md +311 -0
- package/.llm/components/featuresplit.md +5 -0
- package/.llm/components/featurestack.md +227 -0
- package/.llm/components/illustrationcard.md +2 -2
- package/.llm/components/illustrationscene.md +6 -10
- package/.llm/components/imagebanner.md +278 -0
- package/.llm/components/navbar.md +1 -1
- package/.llm/components/navbaritem.md +4 -0
- package/.llm/components/pageheader.md +4 -3
- package/.llm/components/paginationdots.md +6 -1
- package/.llm/components/producthero.md +35 -11
- package/.llm/components/resourcebanner.md +247 -0
- package/.llm/components/scenescroll.md +222 -0
- package/.llm/components/select.md +17 -0
- package/.llm/components/stats.md +219 -0
- package/.llm/components/steps.md +286 -0
- package/.llm/components/stickycards.md +251 -0
- package/.llm/components/tableheadercell.md +19 -0
- package/.llm/components/teamgrid.md +243 -0
- package/.llm/components/testimonialrow.md +5 -0
- package/.llm/components/testimonialslider.md +14 -1
- package/.llm/components/textarea.md +13 -0
- package/.llm/components/textinput.md +13 -0
- package/.llm/components/textscroll.md +187 -0
- package/.llm/components/tiers.md +227 -0
- package/.llm/digest/awards.md +45 -0
- package/.llm/digest/background.md +11 -10
- package/.llm/digest/bottomsheet.md +2 -0
- package/.llm/digest/comparisoncards.md +51 -0
- package/.llm/digest/comparisontable.md +53 -0
- package/.llm/digest/ctabanner.md +4 -4
- package/.llm/digest/ctabannerslider.md +4 -0
- package/.llm/digest/datatable.md +65 -0
- package/.llm/digest/downloadbanner.md +65 -0
- package/.llm/digest/featurecards.md +1 -1
- package/.llm/digest/featurecardscarousel.md +54 -0
- package/.llm/digest/featuresplit.md +1 -0
- package/.llm/digest/featurestack.md +48 -0
- package/.llm/digest/illustrationscene.md +2 -3
- package/.llm/digest/imagebanner.md +64 -0
- package/.llm/digest/navbaritem.md +1 -0
- package/.llm/digest/pageheader.md +2 -1
- package/.llm/digest/paginationdots.md +3 -1
- package/.llm/digest/producthero.md +4 -2
- package/.llm/digest/resourcebanner.md +53 -0
- package/.llm/digest/scenescroll.md +49 -0
- package/.llm/digest/select.md +5 -0
- package/.llm/digest/stats.md +46 -0
- package/.llm/digest/steps.md +55 -0
- package/.llm/digest/stickycards.md +52 -0
- package/.llm/digest/tableheadercell.md +4 -0
- package/.llm/digest/teamgrid.md +53 -0
- package/.llm/digest/testimonialrow.md +2 -0
- package/.llm/digest/testimonialslider.md +4 -0
- package/.llm/digest/textarea.md +4 -0
- package/.llm/digest/textinput.md +4 -0
- package/.llm/digest/textscroll.md +43 -0
- package/.llm/digest/tiers.md +50 -0
- package/.llm/index.md +19 -3
- package/.llm/tokens.md +26 -1
- package/AGENTS.md +17 -1
- package/dist/components/awards-data.d.ts +24 -0
- package/dist/components/awards-data.js +11 -0
- package/dist/components/block-image-data.d.ts +24 -0
- package/dist/components/block-image-data.js +9 -0
- package/dist/components/blocks/awards/Awards.css +134 -0
- package/dist/components/blocks/awards/Awards.d.ts +24 -0
- package/dist/components/blocks/awards/Awards.js +114 -0
- package/dist/components/blocks/awards/Awards.types.d.ts +31 -0
- package/dist/components/blocks/awards/Awards.types.js +16 -0
- package/dist/components/blocks/awards/awards-impl.css +222 -0
- package/dist/components/blocks/cards-of.d.ts +16 -0
- package/dist/components/blocks/cards-of.js +23 -0
- package/dist/components/blocks/comparison-cards/ComparisonCards.css +195 -0
- package/dist/components/blocks/comparison-cards/ComparisonCards.d.ts +24 -0
- package/dist/components/blocks/comparison-cards/ComparisonCards.js +75 -0
- package/dist/components/blocks/comparison-cards/ComparisonCards.types.d.ts +49 -0
- package/dist/components/blocks/comparison-cards/ComparisonCards.types.js +26 -0
- package/dist/components/blocks/comparison-cards/comparison-cards-impl.css +262 -0
- package/dist/components/blocks/comparison-table/ComparisonTable.css +111 -0
- package/dist/components/blocks/comparison-table/ComparisonTable.d.ts +25 -0
- package/dist/components/blocks/comparison-table/ComparisonTable.js +100 -0
- package/dist/components/blocks/comparison-table/ComparisonTable.types.d.ts +36 -0
- package/dist/components/blocks/comparison-table/ComparisonTable.types.js +15 -0
- package/dist/components/blocks/comparison-table/comparison-table-impl.css +143 -0
- package/dist/components/blocks/cta-banner/CtaBanner.css +1 -0
- package/dist/components/blocks/cta-banner/CtaBanner.js +2 -2
- package/dist/components/blocks/cta-banner/CtaBanner.types.d.ts +4 -3
- package/dist/components/blocks/cta-banner/CtaBanner.types.js +1 -1
- package/dist/components/blocks/cta-banner-slider/CtaBannerSlider.css +1 -0
- package/dist/components/blocks/cta-banner-slider/CtaBannerSlider.d.ts +1 -1
- package/dist/components/blocks/cta-banner-slider/CtaBannerSlider.js +6 -2
- package/dist/components/blocks/cta-banner-slider/CtaBannerSlider.types.d.ts +8 -0
- package/dist/components/blocks/cta-banner-slider/CtaBannerSlider.types.js +1 -1
- package/dist/components/blocks/data-table/DataTable.css +170 -0
- package/dist/components/blocks/data-table/DataTable.d.ts +29 -0
- package/dist/components/blocks/data-table/DataTable.js +84 -0
- package/dist/components/blocks/data-table/DataTable.types.d.ts +69 -0
- package/dist/components/blocks/data-table/DataTable.types.js +19 -0
- package/dist/components/blocks/data-table/data-table-impl.css +155 -0
- package/dist/components/blocks/download-banner/DownloadBanner.css +228 -0
- package/dist/components/blocks/download-banner/DownloadBanner.d.ts +28 -0
- package/dist/components/blocks/download-banner/DownloadBanner.js +75 -0
- package/dist/components/blocks/download-banner/DownloadBanner.types.d.ts +56 -0
- package/dist/components/blocks/download-banner/DownloadBanner.types.js +23 -0
- package/dist/components/blocks/download-banner/download-banner-impl.css +216 -0
- package/dist/components/blocks/faq-accordion/FaqAccordion.css +1 -0
- package/dist/components/blocks/faq-accordion/faq-accordion-impl.css +3 -7
- package/dist/components/blocks/feature-bullets/FeatureBullets.css +1 -0
- package/dist/components/blocks/feature-bullets/feature-bullets-impl.css +14 -1
- package/dist/components/blocks/feature-cards/FeatureCards.css +1 -0
- package/dist/components/blocks/feature-cards/FeatureCards.d.ts +2 -1
- package/dist/components/blocks/feature-cards/FeatureCards.js +4 -21
- package/dist/components/blocks/feature-cards/feature-cards-impl.css +10 -9
- package/dist/components/blocks/feature-cards-carousel/FeatureCardsCarousel.css +115 -0
- package/dist/components/blocks/feature-cards-carousel/FeatureCardsCarousel.d.ts +30 -0
- package/dist/components/blocks/feature-cards-carousel/FeatureCardsCarousel.js +160 -0
- package/dist/components/blocks/feature-cards-carousel/FeatureCardsCarousel.types.d.ts +52 -0
- package/dist/components/blocks/feature-cards-carousel/FeatureCardsCarousel.types.js +17 -0
- package/dist/components/blocks/feature-cards-carousel/feature-cards-carousel-impl.css +207 -0
- package/dist/components/blocks/feature-scroll/FeatureScroll.css +1 -0
- package/dist/components/blocks/feature-split/FeatureSplit.css +1 -0
- package/dist/components/blocks/feature-split/feature-split-impl.css +14 -1
- package/dist/components/blocks/feature-stack/FeatureStack.css +86 -0
- package/dist/components/blocks/feature-stack/FeatureStack.d.ts +19 -0
- package/dist/components/blocks/feature-stack/FeatureStack.js +27 -0
- package/dist/components/blocks/feature-stack/FeatureStack.types.d.ts +34 -0
- package/dist/components/blocks/feature-stack/FeatureStack.types.js +14 -0
- package/dist/components/blocks/feature-stack/feature-stack-impl.css +87 -0
- package/dist/components/blocks/image-banner/ImageBanner.css +133 -0
- package/dist/components/blocks/image-banner/ImageBanner.d.ts +32 -0
- package/dist/components/blocks/image-banner/ImageBanner.js +41 -0
- package/dist/components/blocks/image-banner/ImageBanner.types.d.ts +54 -0
- package/dist/components/blocks/image-banner/ImageBanner.types.js +14 -0
- package/dist/components/blocks/image-banner/image-banner-impl.css +281 -0
- package/dist/components/blocks/landing-hero/LandingHero.css +1 -0
- package/dist/components/blocks/logo-columns/LogoColumns.css +1 -0
- package/dist/components/blocks/logo-rows/LogoRows.css +1 -0
- package/dist/components/blocks/page-header/PageHeader.css +1 -0
- package/dist/components/blocks/page-header/PageHeader.js +2 -2
- package/dist/components/blocks/page-header/PageHeader.types.d.ts +4 -2
- package/dist/components/blocks/page-header/PageHeader.types.js +1 -1
- package/dist/components/blocks/page-header/page-header-impl.css +5 -3
- package/dist/components/blocks/product-hero/ProductHero.css +8 -3
- package/dist/components/blocks/product-hero/ProductHero.d.ts +1 -1
- package/dist/components/blocks/product-hero/ProductHero.js +5 -2
- package/dist/components/blocks/product-hero/ProductHero.types.d.ts +5 -1
- package/dist/components/blocks/product-hero/ProductHero.types.js +1 -0
- package/dist/components/blocks/product-hero/product-hero-impl.css +43 -12
- package/dist/components/blocks/resource-banner/ResourceBanner.css +106 -0
- package/dist/components/blocks/resource-banner/ResourceBanner.d.ts +32 -0
- package/dist/components/blocks/resource-banner/ResourceBanner.js +51 -0
- package/dist/components/blocks/resource-banner/ResourceBanner.types.d.ts +44 -0
- package/dist/components/blocks/resource-banner/ResourceBanner.types.js +14 -0
- package/dist/components/blocks/resource-banner/resource-banner-impl.css +69 -0
- package/dist/components/blocks/scene-scroll/SceneScroll.css +93 -0
- package/dist/components/blocks/scene-scroll/SceneScroll.d.ts +36 -0
- package/dist/components/blocks/scene-scroll/SceneScroll.js +54 -0
- package/dist/components/blocks/scene-scroll/SceneScroll.types.d.ts +32 -0
- package/dist/components/blocks/scene-scroll/SceneScroll.types.js +15 -0
- package/dist/components/blocks/scene-scroll/scene-scroll-impl.css +275 -0
- package/dist/components/blocks/stats/Stats.css +139 -0
- package/dist/components/blocks/stats/Stats.d.ts +24 -0
- package/dist/components/blocks/stats/Stats.js +120 -0
- package/dist/components/blocks/stats/Stats.types.d.ts +36 -0
- package/dist/components/blocks/stats/Stats.types.js +19 -0
- package/dist/components/blocks/stats/stats-count.d.ts +34 -0
- package/dist/components/blocks/stats/stats-count.js +61 -0
- package/dist/components/blocks/stats/stats-impl.css +284 -0
- package/dist/components/blocks/stats/use-wheel.d.ts +37 -0
- package/dist/components/blocks/stats/use-wheel.js +126 -0
- package/dist/components/blocks/steps/Steps.css +202 -0
- package/dist/components/blocks/steps/Steps.d.ts +32 -0
- package/dist/components/blocks/steps/Steps.js +65 -0
- package/dist/components/blocks/steps/Steps.types.d.ts +48 -0
- package/dist/components/blocks/steps/Steps.types.js +21 -0
- package/dist/components/blocks/steps/steps-impl.css +216 -0
- package/dist/components/blocks/steps/use-turn.d.ts +33 -0
- package/dist/components/blocks/steps/use-turn.js +75 -0
- package/dist/components/blocks/sticky-cards/StickyCards.css +154 -0
- package/dist/components/blocks/sticky-cards/StickyCards.d.ts +35 -0
- package/dist/components/blocks/sticky-cards/StickyCards.js +153 -0
- package/dist/components/blocks/sticky-cards/StickyCards.types.d.ts +43 -0
- package/dist/components/blocks/sticky-cards/StickyCards.types.js +18 -0
- package/dist/components/blocks/sticky-cards/sticky-cards-impl.css +393 -0
- package/dist/components/blocks/team-grid/TeamGrid.css +159 -0
- package/dist/components/blocks/team-grid/TeamGrid.d.ts +28 -0
- package/dist/components/blocks/team-grid/TeamGrid.js +74 -0
- package/dist/components/blocks/team-grid/TeamGrid.types.d.ts +51 -0
- package/dist/components/blocks/team-grid/TeamGrid.types.js +20 -0
- package/dist/components/blocks/team-grid/team-grid-impl.css +129 -0
- package/dist/components/blocks/testimonial-row/TestimonialRow.css +1 -0
- package/dist/components/blocks/testimonial-row/TestimonialRow.d.ts +1 -1
- package/dist/components/blocks/testimonial-row/TestimonialRow.js +4 -3
- package/dist/components/blocks/testimonial-row/TestimonialRow.types.d.ts +3 -0
- package/dist/components/blocks/testimonial-row/TestimonialRow.types.js +1 -1
- package/dist/components/blocks/testimonial-row/testimonial-row-impl.css +8 -0
- package/dist/components/blocks/testimonial-slider/TestimonialSlider.css +1 -0
- package/dist/components/blocks/testimonial-slider/TestimonialSlider.d.ts +1 -1
- package/dist/components/blocks/testimonial-slider/TestimonialSlider.js +2 -2
- package/dist/components/blocks/testimonial-slider/TestimonialSlider.types.d.ts +8 -0
- package/dist/components/blocks/testimonial-slider/TestimonialSlider.types.js +1 -1
- package/dist/components/blocks/text-scroll/TextScroll.css +53 -0
- package/dist/components/blocks/text-scroll/TextScroll.d.ts +5 -0
- package/dist/components/blocks/text-scroll/TextScroll.js +71 -0
- package/dist/components/blocks/text-scroll/TextScroll.types.d.ts +22 -0
- package/dist/components/blocks/text-scroll/TextScroll.types.js +10 -0
- package/dist/components/blocks/text-scroll/text-scroll-impl.css +115 -0
- package/dist/components/blocks/tiers/Tiers.css +233 -0
- package/dist/components/blocks/tiers/Tiers.d.ts +32 -0
- package/dist/components/blocks/tiers/Tiers.js +68 -0
- package/dist/components/blocks/tiers/Tiers.types.d.ts +45 -0
- package/dist/components/blocks/tiers/Tiers.types.js +25 -0
- package/dist/components/blocks/tiers/tiers-impl.css +185 -0
- package/dist/components/blocks/use-rotation.d.ts +12 -2
- package/dist/components/blocks/use-rotation.js +6 -28
- package/dist/components/comparison-cards-data.d.ts +59 -0
- package/dist/components/comparison-cards-data.js +12 -0
- package/dist/components/comparison-table-data.d.ts +39 -0
- package/dist/components/comparison-table-data.js +11 -0
- package/dist/components/core/accordion-item/AccordionItem.css +1 -5
- package/dist/components/core/background/Background.css +23 -0
- package/dist/components/core/background/Background.d.ts +10 -4
- package/dist/components/core/background/Background.js +16 -7
- package/dist/components/core/background/Background.types.d.ts +11 -8
- package/dist/components/core/background/Background.types.js +3 -1
- package/dist/components/core/background/background-impl.css +334 -1
- package/dist/components/core/background/halftone.d.ts +11 -0
- package/dist/components/core/background/halftone.js +43 -3
- package/dist/components/core/background/patterns.d.ts +66 -0
- package/dist/components/core/background/patterns.js +244 -0
- package/dist/components/core/background/shader.d.ts +44 -0
- package/dist/components/core/background/shader.js +307 -0
- package/dist/components/core/background/use-shader.d.ts +11 -0
- package/dist/components/core/background/use-shader.js +25 -0
- package/dist/components/core/background/use-spotlight.d.ts +2 -1
- package/dist/components/core/background/use-spotlight.js +9 -1
- package/dist/components/core/bottom-sheet/BottomSheet.js +2 -2
- package/dist/components/core/bottom-sheet/BottomSheet.types.d.ts +3 -1
- package/dist/components/core/breadcrumb/Breadcrumb.d.ts +1 -0
- package/dist/components/core/breadcrumb/Breadcrumb.js +1 -0
- package/dist/components/core/breadcrumb/breadcrumb-impl.css +11 -0
- package/dist/components/core/button/button-impl.css +14 -1
- package/dist/components/core/illustration-card/IllustrationCard.js +1 -1
- package/dist/components/core/illustration-card/illustration-card-impl.css +20 -0
- package/dist/components/core/illustration-scene/IllustrationScene.css +4 -7
- package/dist/components/core/illustration-scene/IllustrationScene.types.d.ts +2 -3
- package/dist/components/core/illustration-scene/illustration-scene-impl.css +7 -1
- package/dist/components/core/link/Link.js +7 -3
- package/dist/components/core/link/link-impl.css +29 -2
- package/dist/components/core/navbar/Navbar.css +2 -2
- package/dist/components/core/navbar/Navbar.types.d.ts +1 -1
- package/dist/components/core/navbar-item/NavbarItem.d.ts +2 -1
- package/dist/components/core/navbar-item/NavbarItem.js +3 -10
- package/dist/components/core/navbar-item/NavbarItem.types.d.ts +4 -1
- package/dist/components/core/navbar-item/NavbarItem.types.js +1 -1
- package/dist/components/core/navbar-item/navbar-item-impl.css +10 -0
- package/dist/components/core/navbar-menu/navbar-menu-impl.css +9 -0
- package/dist/components/core/navbar-switcher/navbar-switcher-impl.css +19 -0
- package/dist/components/core/pagination/Pagination.js +1 -1
- package/dist/components/core/pagination/pagination-impl.css +9 -0
- package/dist/components/core/pagination-dots/PaginationDots.d.ts +1 -1
- package/dist/components/core/pagination-dots/PaginationDots.js +3 -3
- package/dist/components/core/pagination-dots/PaginationDots.types.d.ts +3 -1
- package/dist/components/core/segmented-control/SegmentedControl.css +4 -3
- package/dist/components/core/segmented-control/SegmentedControl.js +17 -3
- package/dist/components/core/segmented-control-item/SegmentedControlItem.css +2 -1
- package/dist/components/core/select/Select.js +3 -3
- package/dist/components/core/select/Select.types.d.ts +11 -1
- package/dist/components/core/select/Select.types.js +1 -1
- package/dist/components/core/tab-list/TabList.js +9 -1
- package/dist/components/core/table-header-cell/TableHeaderCell.d.ts +1 -1
- package/dist/components/core/table-header-cell/TableHeaderCell.js +5 -2
- package/dist/components/core/table-header-cell/TableHeaderCell.types.d.ts +7 -1
- package/dist/components/core/table-header-cell/TableHeaderCell.types.js +1 -1
- package/dist/components/core/text-area/TextArea.d.ts +1 -1
- package/dist/components/core/text-area/TextArea.js +2 -2
- package/dist/components/core/text-area/TextArea.types.d.ts +9 -1
- package/dist/components/core/text-area/TextArea.types.js +1 -1
- package/dist/components/core/text-input/TextInput.d.ts +1 -1
- package/dist/components/core/text-input/TextInput.js +2 -2
- package/dist/components/core/text-input/TextInput.types.d.ts +9 -1
- package/dist/components/core/text-input/TextInput.types.js +1 -1
- package/dist/components/data-table-data.d.ts +33 -0
- package/dist/components/data-table-data.js +12 -0
- package/dist/components/download-banner-data.d.ts +52 -0
- package/dist/components/download-banner-data.js +11 -0
- package/dist/components/index.d.ts +45 -0
- package/dist/components/index.js +32 -0
- package/dist/components/resource-banner-data.d.ts +34 -0
- package/dist/components/resource-banner-data.js +13 -0
- package/dist/components/scene-scroll-data.d.ts +24 -0
- package/dist/components/scene-scroll-data.js +9 -0
- package/dist/components/stats-data.d.ts +28 -0
- package/dist/components/stats-data.js +11 -0
- package/dist/components/steps-data.d.ts +38 -0
- package/dist/components/steps-data.js +13 -0
- package/dist/components/sticky-cards-data.d.ts +43 -0
- package/dist/components/sticky-cards-data.js +12 -0
- package/dist/components/team-grid-data.d.ts +38 -0
- package/dist/components/team-grid-data.js +11 -0
- package/dist/components/tiers-data.d.ts +47 -0
- package/dist/components/tiers-data.js +13 -0
- package/dist/marketing.css +77 -28
- package/package.json +1 -1
|
@@ -36,9 +36,9 @@ import { pageHeaderDefaults, pageHeaderParts } from './PageHeader.types.js';
|
|
|
36
36
|
* region landmark once it has a name, and a band that announced itself as an unnamed section is one
|
|
37
37
|
* more thing a screen reader user walks through rather than a place they can skip to.
|
|
38
38
|
*/
|
|
39
|
-
export function PageHeader({ eyebrow, title, headingLevel = pageHeaderDefaults.headingLevel, description, actions, background, }) {
|
|
39
|
+
export function PageHeader({ eyebrow, title, headingLevel = pageHeaderDefaults.headingLevel, description, actions, background = pageHeaderDefaults.background, }) {
|
|
40
40
|
const titleId = useId();
|
|
41
41
|
const [band, revealed] = useReveal();
|
|
42
42
|
const Title = headingLevel === 'h2' ? 'h2' : 'h1';
|
|
43
|
-
return (_jsxs("section", { className: pageHeaderParts.root, "data-background": background, "aria-labelledby": titleId, children: [
|
|
43
|
+
return (_jsxs("section", { className: pageHeaderParts.root, "data-background": background, "aria-labelledby": titleId, children: [_jsx(Background, { tone: "dark", pattern: background, children: null }), _jsx("div", { className: pageHeaderParts.inner, ref: band, "data-revealed": revealed, children: _jsxs("div", { className: pageHeaderParts.content, children: [_jsxs("div", { className: pageHeaderParts.text, children: [given(eyebrow) ? (_jsx("p", { className: pageHeaderParts.eyebrow, ...arriving(0), children: eyebrow })) : null, _jsx(Title, { className: pageHeaderParts.title, ...arriving(1), id: titleId, children: title }), given(description) ? (_jsx("p", { className: pageHeaderParts.description, ...arriving(2), children: description })) : null] }), actions ? (_jsx("div", { className: pageHeaderParts.actions, ...arriving(3), children: actions })) : null] }) })] }));
|
|
44
44
|
}
|
|
@@ -14,9 +14,10 @@ export interface PageHeaderOwnProps {
|
|
|
14
14
|
/** The one or two things the page wants a reader to do. Composed by the page rather than described to this component, so a call to action is the same Button here as anywhere else on the site */
|
|
15
15
|
actions?: ReactNode;
|
|
16
16
|
/**
|
|
17
|
-
* `
|
|
17
|
+
* `grid` — The default: the band's rule grid, lit — hairlines a pitch apart rising from a soft bloom at the band's foot, a brighter point where two lines cross and a short dash of light running along every few, brightening around the pointer. Drawn by Background as a layer under the content; before its shader has drawn, and where it cannot, the same rules painted by the stylesheet, so the band is never bare.
|
|
18
|
+
* `halftone` — A halftone drawn behind the band's content: coral dots blending to white at the glow's heart, on the band's own dark ground, following the pointer over the band. Drawn by Background, placed as a layer under the content, so the band's own layout is untouched. It replaces the grid rather than joining it: two patterns on one band are texture fighting texture.
|
|
18
19
|
*/
|
|
19
|
-
background?: 'halftone';
|
|
20
|
+
background?: 'grid' | 'halftone';
|
|
20
21
|
}
|
|
21
22
|
export type PageHeaderProps = PageHeaderOwnProps;
|
|
22
23
|
/** The class each part carries. Apply these — do not retype them. */
|
|
@@ -33,4 +34,5 @@ export declare const pageHeaderParts: {
|
|
|
33
34
|
/** Generated so defaults cannot drift from the contract. */
|
|
34
35
|
export declare const pageHeaderDefaults: {
|
|
35
36
|
readonly headingLevel: "h1";
|
|
37
|
+
readonly background: "grid";
|
|
36
38
|
};
|
|
@@ -11,4 +11,4 @@ export const pageHeaderParts = {
|
|
|
11
11
|
actions: 'dds-pageheader__actions',
|
|
12
12
|
};
|
|
13
13
|
/** Generated so defaults cannot drift from the contract. */
|
|
14
|
-
export const pageHeaderDefaults = { headingLevel: 'h1' };
|
|
14
|
+
export const pageHeaderDefaults = { headingLevel: 'h1', background: 'grid' };
|
|
@@ -176,9 +176,11 @@
|
|
|
176
176
|
}
|
|
177
177
|
|
|
178
178
|
/*
|
|
179
|
-
* With
|
|
180
|
-
*
|
|
179
|
+
* With a pattern drawn the painted rule grid steps aside — which is always, now the lit grid is the
|
|
180
|
+
* band's default. The lit grid paints the same rules itself until its shader has drawn, and two
|
|
181
|
+
* patterns on one band are texture fighting texture. The rules above stay for a band rendered
|
|
182
|
+
* without the attribute, so it is never bare.
|
|
181
183
|
*/
|
|
182
|
-
:where([data-dds-context="marketing"]) .dds-pageheader[data-background
|
|
184
|
+
:where([data-dds-context="marketing"]) .dds-pageheader[data-background] {
|
|
183
185
|
background-image: none;
|
|
184
186
|
}
|
|
@@ -7,6 +7,7 @@
|
|
|
7
7
|
inline-size: 100%;
|
|
8
8
|
justify-content: center;
|
|
9
9
|
overflow: hidden;
|
|
10
|
+
overflow-wrap: anywhere;
|
|
10
11
|
position: relative;
|
|
11
12
|
background-color: var(--color-bg-brand-strong);
|
|
12
13
|
color: var(--color-fg-on-brand-strong);
|
|
@@ -78,9 +79,13 @@
|
|
|
78
79
|
|
|
79
80
|
:where([data-dds-context="marketing"]) .dds-producthero .dds-producthero__media {
|
|
80
81
|
min-inline-size: 0;
|
|
81
|
-
overflow:
|
|
82
|
+
overflow: clip;
|
|
82
83
|
position: relative;
|
|
83
|
-
|
|
84
|
-
border-radius: var(--radius-
|
|
84
|
+
border-start-end-radius: var(--radius-container);
|
|
85
|
+
border-start-start-radius: var(--radius-container);
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
:where([data-dds-context="marketing"]) .dds-producthero .dds-producthero__image {
|
|
89
|
+
display: block;
|
|
85
90
|
}
|
|
86
91
|
|
|
@@ -32,4 +32,4 @@ export type { ProductHeroProps };
|
|
|
32
32
|
* region landmark once it has a name, and a band that announced itself as an unnamed section is one
|
|
33
33
|
* more thing a screen reader user walks through rather than a place they can skip to.
|
|
34
34
|
*/
|
|
35
|
-
export declare function ProductHero({ eyebrow, title, headingLevel, description, actions, media, backgroundImage, }: ProductHeroProps): import("react").JSX.Element;
|
|
35
|
+
export declare function ProductHero({ eyebrow, title, headingLevel, description, actions, image, media, backgroundImage, }: ProductHeroProps): import("react").JSX.Element;
|
|
@@ -36,7 +36,7 @@ import { productHeroDefaults, productHeroParts, } from './ProductHero.types.js';
|
|
|
36
36
|
* region landmark once it has a name, and a band that announced itself as an unnamed section is one
|
|
37
37
|
* more thing a screen reader user walks through rather than a place they can skip to.
|
|
38
38
|
*/
|
|
39
|
-
export function ProductHero({ eyebrow, title, headingLevel = productHeroDefaults.headingLevel, description, actions, media, backgroundImage, }) {
|
|
39
|
+
export function ProductHero({ eyebrow, title, headingLevel = productHeroDefaults.headingLevel, description, actions, image, media, backgroundImage, }) {
|
|
40
40
|
const titleId = useId();
|
|
41
41
|
const [band, revealed] = useReveal();
|
|
42
42
|
const Title = headingLevel === 'h2' ? 'h2' : 'h1';
|
|
@@ -44,5 +44,8 @@ export function ProductHero({ eyebrow, title, headingLevel = productHeroDefaults
|
|
|
44
44
|
/* The one inline style here, and it is a value rather than a decision: which photograph,
|
|
45
45
|
supplied by the page. How it is drawn — the cover fit and the position —
|
|
46
46
|
is in the stylesheet, where it can be reasoned about. */
|
|
47
|
-
style: given(backgroundImage) ? { backgroundImage: `url(${backgroundImage})` } : undefined, children: _jsx("div", { className: productHeroParts.inner, ref: band, "data-revealed": revealed, children: _jsxs("div", { className: productHeroParts.content, children: [_jsxs("div", { className: productHeroParts.text, children: [given(eyebrow) ? (_jsx("p", { className: productHeroParts.eyebrow, ...arriving(0), children: eyebrow })) : null, _jsx(Title, { className: productHeroParts.title, ...arriving(1), id: titleId, children: title }), given(description) ? (_jsx("p", { className: productHeroParts.description, ...arriving(2), children: description })) : null] }), actions ? (_jsx("div", { className: productHeroParts.actions, ...arriving(3), children: actions })) : null,
|
|
47
|
+
style: given(backgroundImage) ? { backgroundImage: `url(${backgroundImage})` } : undefined, children: _jsx("div", { className: productHeroParts.inner, ref: band, "data-revealed": revealed, children: _jsxs("div", { className: productHeroParts.content, children: [_jsxs("div", { className: productHeroParts.text, children: [given(eyebrow) ? (_jsx("p", { className: productHeroParts.eyebrow, ...arriving(0), children: eyebrow })) : null, _jsx(Title, { className: productHeroParts.title, ...arriving(1), id: titleId, children: title }), given(description) ? (_jsx("p", { className: productHeroParts.description, ...arriving(2), children: description })) : null] }), actions ? (_jsx("div", { className: productHeroParts.actions, ...arriving(3), children: actions })) : null, image ? (
|
|
48
|
+
// The picture at its own shape: drawn here so the band can size it, and read for its
|
|
49
|
+
// `alt`, which the page leaves empty where the claim already names it.
|
|
50
|
+
_jsx("div", { className: productHeroParts.media, ...arriving(4), children: _jsx("img", { className: productHeroParts.image, src: image.src, alt: image.alt, width: image.width, height: image.height, decoding: "async" }) })) : media ? (_jsx("div", { className: productHeroParts.media, ...arriving(4), "aria-hidden": "true", children: media })) : null] }) }) }));
|
|
48
51
|
}
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import type { ReactNode } from 'react';
|
|
2
|
+
import type { BlockImage } from '../../block-image-data.js';
|
|
2
3
|
export interface ProductHeroOwnProps {
|
|
3
4
|
/** A word or two placing the page before its title names it — a product family, a market, a campaign */
|
|
4
5
|
eyebrow?: string;
|
|
@@ -13,7 +14,9 @@ export interface ProductHeroOwnProps {
|
|
|
13
14
|
description?: string;
|
|
14
15
|
/** The one or two things the page wants a reader to do. Composed by the page rather than described to this component, so a call to action is the same Button here as anywhere else on the site */
|
|
15
16
|
actions?: ReactNode;
|
|
16
|
-
/** The product itself, under the claim and the actions
|
|
17
|
+
/** The product itself, under the claim and the actions, drawn at the picture's own proportions — a square screenshot stays square, a tall phone stays tall — and only held to the screen's limit: no taller than aspect.portrait of the column on a phone, no taller than half the band from the fold. Never cropped. Give its width and height so the band reserves its shape before it loads. `alt` empty when the claim already names what it shows. */
|
|
18
|
+
image?: BlockImage;
|
|
19
|
+
/** A product picture in a shape the page fixes on purpose — an AspectRatio box, which keeps its ratio across the column. Prefer `image`, which keeps the picture's own shape and adapts to it. */
|
|
17
20
|
media?: ReactNode;
|
|
18
21
|
/** A photograph filling the whole band. It is shown as it is — nothing is painted over it, so choose one already dark enough that the title reads on it */
|
|
19
22
|
backgroundImage?: string;
|
|
@@ -30,6 +33,7 @@ export declare const productHeroParts: {
|
|
|
30
33
|
readonly description: "dds-producthero__description";
|
|
31
34
|
readonly actions: "dds-producthero__actions";
|
|
32
35
|
readonly media: "dds-producthero__media";
|
|
36
|
+
readonly image: "dds-producthero__image";
|
|
33
37
|
};
|
|
34
38
|
/** Generated so defaults cannot drift from the contract. */
|
|
35
39
|
export declare const productHeroDefaults: {
|
|
@@ -10,6 +10,7 @@ export const productHeroParts = {
|
|
|
10
10
|
description: 'dds-producthero__description',
|
|
11
11
|
actions: 'dds-producthero__actions',
|
|
12
12
|
media: 'dds-producthero__media',
|
|
13
|
+
image: 'dds-producthero__image',
|
|
13
14
|
};
|
|
14
15
|
/** Generated so defaults cannot drift from the contract. */
|
|
15
16
|
export const productHeroDefaults = { headingLevel: 'h1' };
|
|
@@ -86,7 +86,7 @@
|
|
|
86
86
|
* picture in something: `object-fit` does nothing on a `<div>`, so a rule aimed at the slot's
|
|
87
87
|
* immediate child was silently a no-op whenever that child was a ratio box.
|
|
88
88
|
*/
|
|
89
|
-
:where([data-dds-context="marketing"]) .dds-producthero .dds-producthero__media >
|
|
89
|
+
:where([data-dds-context="marketing"]) .dds-producthero .dds-producthero__media > :not(.dds-producthero__image) {
|
|
90
90
|
inline-size: 100%;
|
|
91
91
|
}
|
|
92
92
|
|
|
@@ -173,10 +173,39 @@
|
|
|
173
173
|
padding-block-end: 0;
|
|
174
174
|
}
|
|
175
175
|
|
|
176
|
+
/*
|
|
177
|
+
* The picture keeps its own shape; the screen only decides how tall it may grow.
|
|
178
|
+
*
|
|
179
|
+
* Given `image`, the frame wraps the picture rather than a box the band chose — as wide as the
|
|
180
|
+
* picture's shape allows, up to the column, centred — so a square screenshot is drawn square and a
|
|
181
|
+
* tall phone tall, whatever shape the band's own example is. The tallest it may be is aspect.portrait
|
|
182
|
+
* of the column on a phone, said as the factor 1.25, and half the band from the fold. A picture past
|
|
183
|
+
* that is drawn smaller, keeping its shape; nothing crops it. FeatureStack's rule, for the same
|
|
184
|
+
* reason.
|
|
185
|
+
*
|
|
186
|
+
* Given `media`, an AspectRatio box, the page fixed the shape on purpose: the box has no width of its
|
|
187
|
+
* own to wrap, so the frame takes the column's width and the box its shape across it.
|
|
188
|
+
*/
|
|
189
|
+
/* Set on the frame rather than the band: a container query styles what is inside the container,
|
|
190
|
+
never the container itself, so the band could not take the fold's value. */
|
|
176
191
|
:where([data-dds-context="marketing"]) .dds-producthero .dds-producthero__media {
|
|
192
|
+
--dds-producthero-tallest: calc((100cqi - 2 * var(--space-inset-page)) * 1.25);
|
|
193
|
+
inline-size: fit-content;
|
|
194
|
+
margin-inline: auto;
|
|
195
|
+
max-inline-size: 100%;
|
|
196
|
+
}
|
|
197
|
+
|
|
198
|
+
:where([data-dds-context="marketing"]) .dds-producthero .dds-producthero__media:not(:has(> .dds-producthero__image)) {
|
|
177
199
|
inline-size: 100%;
|
|
178
200
|
}
|
|
179
201
|
|
|
202
|
+
:where([data-dds-context="marketing"]) .dds-producthero .dds-producthero__image {
|
|
203
|
+
block-size: auto;
|
|
204
|
+
inline-size: auto;
|
|
205
|
+
max-block-size: var(--dds-producthero-tallest);
|
|
206
|
+
max-inline-size: 100%;
|
|
207
|
+
}
|
|
208
|
+
|
|
180
209
|
/*
|
|
181
210
|
* Below the fold the whole column sits at the foot, rather than the picture alone.
|
|
182
211
|
*
|
|
@@ -256,6 +285,16 @@
|
|
|
256
285
|
max-inline-size: min(80%, 50cqh);
|
|
257
286
|
}
|
|
258
287
|
|
|
288
|
+
/* Given `image`, the cap is on the height — half the band — and the width follows the picture's
|
|
289
|
+
own shape, up to most of the column. */
|
|
290
|
+
:where([data-dds-context="marketing"]) .dds-producthero:has(.dds-producthero__image) .dds-producthero__media {
|
|
291
|
+
max-inline-size: 80%;
|
|
292
|
+
}
|
|
293
|
+
|
|
294
|
+
:where([data-dds-context="marketing"]) .dds-producthero .dds-producthero__media {
|
|
295
|
+
--dds-producthero-tallest: 50cqh;
|
|
296
|
+
}
|
|
297
|
+
|
|
259
298
|
/*
|
|
260
299
|
* The claim starts below where a navigation bar would be.
|
|
261
300
|
*
|
|
@@ -275,20 +314,12 @@
|
|
|
275
314
|
* does not make it taller. Without the second half of this the cap clipped the picture instead
|
|
276
315
|
* of resizing it.
|
|
277
316
|
*/
|
|
278
|
-
:where([data-dds-context="marketing"]) .dds-producthero .dds-producthero__media >
|
|
279
|
-
|
|
280
|
-
inline-size: auto;
|
|
281
|
-
margin-inline: auto;
|
|
282
|
-
max-inline-size: 100%;
|
|
317
|
+
:where([data-dds-context="marketing"]) .dds-producthero .dds-producthero__media > :not(.dds-producthero__image) {
|
|
318
|
+
inline-size: 100%;
|
|
283
319
|
}
|
|
284
320
|
}
|
|
285
321
|
|
|
286
|
-
|
|
287
|
-
block-size: 100%;
|
|
288
|
-
display: block;
|
|
289
|
-
inline-size: 100%;
|
|
290
|
-
object-fit: cover;
|
|
291
|
-
}
|
|
322
|
+
|
|
292
323
|
|
|
293
324
|
/*
|
|
294
325
|
* The band rounds off as it leaves.
|
|
@@ -0,0 +1,106 @@
|
|
|
1
|
+
/* GENERATED from resourcebanner.contract.json. Do not edit. */
|
|
2
|
+
|
|
3
|
+
:where([data-dds-context="marketing"]) .dds-resourcebanner {
|
|
4
|
+
box-sizing: border-box;
|
|
5
|
+
container-type: inline-size;
|
|
6
|
+
display: flex;
|
|
7
|
+
inline-size: 100%;
|
|
8
|
+
justify-content: center;
|
|
9
|
+
overflow-wrap: anywhere;
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
:where([data-dds-context="marketing"]) .dds-resourcebanner .dds-resourcebanner__inner {
|
|
13
|
+
box-sizing: border-box;
|
|
14
|
+
display: flex;
|
|
15
|
+
flex-direction: column;
|
|
16
|
+
inline-size: 100%;
|
|
17
|
+
min-inline-size: 0;
|
|
18
|
+
max-inline-size: var(--size-content-max);
|
|
19
|
+
padding-block: var(--space-section-default);
|
|
20
|
+
padding-inline: var(--space-inset-page);
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
:where([data-dds-context="marketing"]) .dds-resourcebanner .dds-resourcebanner__panel {
|
|
24
|
+
align-items: center;
|
|
25
|
+
box-sizing: border-box;
|
|
26
|
+
display: grid;
|
|
27
|
+
min-inline-size: 0;
|
|
28
|
+
border-radius: var(--radius-surface);
|
|
29
|
+
color: var(--color-fg-on-brand-strong);
|
|
30
|
+
column-gap: var(--space-heading-content);
|
|
31
|
+
padding-block: var(--space-inset-card);
|
|
32
|
+
padding-inline: var(--space-inset-card);
|
|
33
|
+
row-gap: var(--space-heading-content);
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
:where([data-dds-context="marketing"]) .dds-resourcebanner .dds-resourcebanner__content {
|
|
37
|
+
display: flex;
|
|
38
|
+
flex-direction: column;
|
|
39
|
+
min-inline-size: 0;
|
|
40
|
+
row-gap: var(--space-heading-title-description);
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
:where([data-dds-context="marketing"]) .dds-resourcebanner .dds-resourcebanner__title {
|
|
44
|
+
margin-block: 0;
|
|
45
|
+
text-wrap: balance;
|
|
46
|
+
font-family: var(--font-h2-family);
|
|
47
|
+
font-size: var(--font-h2-size);
|
|
48
|
+
font-weight: var(--font-h2-weight);
|
|
49
|
+
letter-spacing: var(--font-h2-letter-spacing);
|
|
50
|
+
line-height: var(--font-h2-line-height);
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
:where([data-dds-context="marketing"]) .dds-resourcebanner .dds-resourcebanner__description {
|
|
54
|
+
margin-block: 0;
|
|
55
|
+
font-family: var(--font-body-md-family);
|
|
56
|
+
font-size: var(--font-body-md-size);
|
|
57
|
+
font-weight: var(--font-body-md-weight);
|
|
58
|
+
letter-spacing: var(--font-body-md-letter-spacing);
|
|
59
|
+
line-height: var(--font-body-md-line-height);
|
|
60
|
+
max-inline-size: var(--size-measure-description);
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
:where([data-dds-context="marketing"]) .dds-resourcebanner .dds-resourcebanner__list {
|
|
64
|
+
display: flex;
|
|
65
|
+
flex-direction: column;
|
|
66
|
+
list-style: none;
|
|
67
|
+
margin-block: 0;
|
|
68
|
+
min-inline-size: 0;
|
|
69
|
+
padding-inline-start: 0;
|
|
70
|
+
row-gap: var(--space-gap-md);
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
:where([data-dds-context="marketing"]) .dds-resourcebanner .dds-resourcebanner__item {
|
|
74
|
+
display: flex;
|
|
75
|
+
position: relative;
|
|
76
|
+
min-block-size: var(--size-target-min);
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
:where([data-dds-context="marketing"]) .dds-resourcebanner[data-ground="page"] {
|
|
80
|
+
background-color: var(--color-bg-page);
|
|
81
|
+
color: var(--color-fg-default);
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
:where([data-dds-context="marketing"]) .dds-resourcebanner[data-ground="page"] .dds-resourcebanner__panel {
|
|
85
|
+
background-color: var(--color-bg-surface-card-strong);
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
:where([data-dds-context="marketing"]) .dds-resourcebanner[data-ground="strong"] {
|
|
89
|
+
background-color: var(--color-bg-brand-strong);
|
|
90
|
+
color: var(--color-fg-on-brand-strong);
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
:where([data-dds-context="marketing"]) .dds-resourcebanner[data-ground="strong"] .dds-resourcebanner__panel {
|
|
94
|
+
background-color: var(--color-bg-surface-card-strong);
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
:where([data-dds-context="marketing"]) .dds-resourcebanner[data-ground="subtle"] {
|
|
98
|
+
background-color: var(--color-bg-page);
|
|
99
|
+
background-image: linear-gradient(var(--color-bg-band-subtle), var(--color-bg-band-subtle));
|
|
100
|
+
color: var(--color-fg-default);
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
:where([data-dds-context="marketing"]) .dds-resourcebanner[data-ground="subtle"] .dds-resourcebanner__panel {
|
|
104
|
+
background-color: var(--color-bg-surface-card-strong-raised);
|
|
105
|
+
}
|
|
106
|
+
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
import './ResourceBanner.css';
|
|
2
|
+
import './resource-banner-impl.css';
|
|
3
|
+
import '../block-reveal.css';
|
|
4
|
+
import { type ResourceBannerProps } from './ResourceBanner.types.js';
|
|
5
|
+
export type { ResourceBannerProps };
|
|
6
|
+
/**
|
|
7
|
+
* A dark panel pointing readers at related guides, policies and reference pages — the block that
|
|
8
|
+
* ends an informational section with "here's where to read more".
|
|
9
|
+
*
|
|
10
|
+
* The reference site's ResourceBanner, named the same: a heading and a line on one side, a stack
|
|
11
|
+
* of links on the other, in a rounded dark card. The panel carries its own ink, so `ground`
|
|
12
|
+
* changes only what is around it.
|
|
13
|
+
*
|
|
14
|
+
* The links are records rather than nodes, for the reason TestimonialRow's reviews are: a resource
|
|
15
|
+
* is a name and a destination, and every one is drawn the same way. That is what lets the block
|
|
16
|
+
* say the two things a link has to say about itself in the same words on every row — that it
|
|
17
|
+
* leaves the site, or that it saves a file. Each is a standalone Link in the panel's own ink, so
|
|
18
|
+
* the focus ring and the hover are Link's and the marks are Link's: its arrow for a page here, its
|
|
19
|
+
* up-right arrow for a page elsewhere. A download is marked with a file before its words instead,
|
|
20
|
+
* because an arrow pointing onward promises a page.
|
|
21
|
+
*
|
|
22
|
+
* Link's marks are decoration and announced as nothing, so an external link and a download end
|
|
23
|
+
* their accessible name with words that are heard and never drawn — `externalLabel` and
|
|
24
|
+
* `downloadLabel`, translated with the page. Appended rather than put in an `aria-label`, so the
|
|
25
|
+
* name still starts with the words a reader sees and a voice user can say them.
|
|
26
|
+
*
|
|
27
|
+
* `<ul>` at every width, so one link and four are one layout, and a screen reader announces how
|
|
28
|
+
* many there are before reading the first.
|
|
29
|
+
*
|
|
30
|
+
* `'use client'` for `useId`, which names the region by its heading, and for the arrival.
|
|
31
|
+
*/
|
|
32
|
+
export declare function ResourceBanner({ ground, title, headingLevel, description, links, externalLabel, downloadLabel, }: ResourceBannerProps): import("react").JSX.Element;
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
'use client';
|
|
2
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
3
|
+
import { useId } from 'react';
|
|
4
|
+
import { FileArrowDownSolidIcon } from '@deriv-com/quill-icons-web';
|
|
5
|
+
import './ResourceBanner.css';
|
|
6
|
+
import './resource-banner-impl.css';
|
|
7
|
+
import '../block-reveal.css';
|
|
8
|
+
import { arriving, useReveal } from '../use-reveal.js';
|
|
9
|
+
import { given } from '../../given.js';
|
|
10
|
+
import { visuallyHidden } from '../../visually-hidden.js';
|
|
11
|
+
import { Link } from '../../core/link/Link.js';
|
|
12
|
+
import { resourceBannerDefaults, resourceBannerParts, } from './ResourceBanner.types.js';
|
|
13
|
+
/**
|
|
14
|
+
* A dark panel pointing readers at related guides, policies and reference pages — the block that
|
|
15
|
+
* ends an informational section with "here's where to read more".
|
|
16
|
+
*
|
|
17
|
+
* The reference site's ResourceBanner, named the same: a heading and a line on one side, a stack
|
|
18
|
+
* of links on the other, in a rounded dark card. The panel carries its own ink, so `ground`
|
|
19
|
+
* changes only what is around it.
|
|
20
|
+
*
|
|
21
|
+
* The links are records rather than nodes, for the reason TestimonialRow's reviews are: a resource
|
|
22
|
+
* is a name and a destination, and every one is drawn the same way. That is what lets the block
|
|
23
|
+
* say the two things a link has to say about itself in the same words on every row — that it
|
|
24
|
+
* leaves the site, or that it saves a file. Each is a standalone Link in the panel's own ink, so
|
|
25
|
+
* the focus ring and the hover are Link's and the marks are Link's: its arrow for a page here, its
|
|
26
|
+
* up-right arrow for a page elsewhere. A download is marked with a file before its words instead,
|
|
27
|
+
* because an arrow pointing onward promises a page.
|
|
28
|
+
*
|
|
29
|
+
* Link's marks are decoration and announced as nothing, so an external link and a download end
|
|
30
|
+
* their accessible name with words that are heard and never drawn — `externalLabel` and
|
|
31
|
+
* `downloadLabel`, translated with the page. Appended rather than put in an `aria-label`, so the
|
|
32
|
+
* name still starts with the words a reader sees and a voice user can say them.
|
|
33
|
+
*
|
|
34
|
+
* `<ul>` at every width, so one link and four are one layout, and a screen reader announces how
|
|
35
|
+
* many there are before reading the first.
|
|
36
|
+
*
|
|
37
|
+
* `'use client'` for `useId`, which names the region by its heading, and for the arrival.
|
|
38
|
+
*/
|
|
39
|
+
export function ResourceBanner({ ground = resourceBannerDefaults.ground, title, headingLevel = resourceBannerDefaults.headingLevel, description, links, externalLabel = resourceBannerDefaults.externalLabel, downloadLabel = resourceBannerDefaults.downloadLabel, }) {
|
|
40
|
+
const titleId = useId();
|
|
41
|
+
const [band, revealed] = useReveal();
|
|
42
|
+
const Title = headingLevel;
|
|
43
|
+
return (_jsx("section", { className: resourceBannerParts.root, "data-ground": ground, "aria-labelledby": titleId, children: _jsx("div", { className: resourceBannerParts.inner, ref: band, "data-revealed": revealed, children: _jsxs("div", { className: resourceBannerParts.panel, children: [_jsxs("div", { className: resourceBannerParts.content, children: [_jsx(Title, { className: resourceBannerParts.title, id: titleId, ...arriving(0), children: title }), given(description) ? (_jsx("p", { className: resourceBannerParts.description, ...arriving(1), children: description })) : null] }), _jsx("ul", { className: resourceBannerParts.list, children: links
|
|
44
|
+
.filter((link) => given(link.label) && given(link.href))
|
|
45
|
+
.map((link, at) => (
|
|
46
|
+
/* Keyed by where it goes and what it is called. Two rows the same in both are
|
|
47
|
+
one resource listed twice, which is not a key collision worth tolerating.
|
|
48
|
+
|
|
49
|
+
The rows arrive after the heading and its line, in the order they are read. */
|
|
50
|
+
_jsx("li", { className: resourceBannerParts.item, ...arriving(2 + at), children: _jsxs(Link, { href: link.href, tone: "inherit", external: link.external === true, download: link.download === true ? true : undefined, showIcon: link.download === true ? false : undefined, iconLeading: link.download === true ? _jsx(FileArrowDownSolidIcon, {}) : undefined, children: [link.label, link.external === true ? ' ' : null, link.external === true ? _jsx("span", { style: visuallyHidden, children: externalLabel }) : null, link.download === true ? ' ' : null, link.download === true ? _jsx("span", { style: visuallyHidden, children: downloadLabel }) : null] }) }, `${link.href}\u0000${link.label}`))) })] }) }) }));
|
|
51
|
+
}
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
import type { ResourceBannerLink } from '../../resource-banner-data.js';
|
|
2
|
+
export interface ResourceBannerOwnProps {
|
|
3
|
+
/**
|
|
4
|
+
* `page` — The default, and the page's own white. A section that has nothing to separate itself from what is above it
|
|
5
|
+
* `subtle` — The reference design's arrangement: the dark panel on the light grey band. The one to reach for when the section ends a run of white ones and wants to read as its close. Painted as the band's tint laid over the page's own ground, so it is the same grey whatever is behind the section.
|
|
6
|
+
* `strong` — `color.bg.brand-strong`, the dark band. The panel is a step lighter than it, so it still reads as a panel — but a dark panel on a dark band is a quiet one, and this is for a page whose sections around it are already dark
|
|
7
|
+
*/
|
|
8
|
+
ground?: 'page' | 'subtle' | 'strong';
|
|
9
|
+
/** Always. What the links are for, in a few words — "Learn more about staying safe", "Read more about trading risks". */
|
|
10
|
+
title: string;
|
|
11
|
+
/**
|
|
12
|
+
* `h2` — The default: the block is a section of the page, under the page's own h1
|
|
13
|
+
* `h3` — The block closes a section that already carries the h2 it belongs to
|
|
14
|
+
* `h4` — The block closes a subsection under an h3, on a long legal or help page whose outline runs that deep
|
|
15
|
+
*/
|
|
16
|
+
headingLevel?: 'h2' | 'h3' | 'h4';
|
|
17
|
+
/** One sentence introducing the links — what the reader will find there, or why it is worth reading. */
|
|
18
|
+
description?: string;
|
|
19
|
+
/** Always. The resources, in the order they are read — one to four, each named for what is there: the guide, the policy, the page. Mark one `external` when it leaves the site, so it opens in a new tab and says so, and `download` when it is a file rather than a page. A row with no label or no href is dropped rather than drawn. */
|
|
20
|
+
links: ResourceBannerLink[];
|
|
21
|
+
/** What an external link's accessible name ends with, so a reader who cannot see the up-right mark is told before their tab changes. Never drawn — the mark says it to everyone else. Translate it with the page. */
|
|
22
|
+
externalLabel?: string;
|
|
23
|
+
/** What a download's accessible name ends with, so a reader who cannot see the file mark knows the link saves something rather than opening a page. Never drawn. Translate it with the page, and name the format in the link's own label when it matters — "Risk disclosure (PDF)". */
|
|
24
|
+
downloadLabel?: string;
|
|
25
|
+
}
|
|
26
|
+
export type ResourceBannerProps = ResourceBannerOwnProps;
|
|
27
|
+
/** The class each part carries. Apply these — do not retype them. */
|
|
28
|
+
export declare const resourceBannerParts: {
|
|
29
|
+
readonly root: "dds-resourcebanner";
|
|
30
|
+
readonly inner: "dds-resourcebanner__inner";
|
|
31
|
+
readonly panel: "dds-resourcebanner__panel";
|
|
32
|
+
readonly content: "dds-resourcebanner__content";
|
|
33
|
+
readonly title: "dds-resourcebanner__title";
|
|
34
|
+
readonly description: "dds-resourcebanner__description";
|
|
35
|
+
readonly list: "dds-resourcebanner__list";
|
|
36
|
+
readonly item: "dds-resourcebanner__item";
|
|
37
|
+
};
|
|
38
|
+
/** Generated so defaults cannot drift from the contract. */
|
|
39
|
+
export declare const resourceBannerDefaults: {
|
|
40
|
+
readonly ground: "page";
|
|
41
|
+
readonly headingLevel: "h2";
|
|
42
|
+
readonly externalLabel: "(opens in a new tab)";
|
|
43
|
+
readonly downloadLabel: "(downloads a file)";
|
|
44
|
+
};
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
// GENERATED from resource-banner.contract.json. Do not edit.
|
|
2
|
+
/** The class each part carries. Apply these — do not retype them. */
|
|
3
|
+
export const resourceBannerParts = {
|
|
4
|
+
root: 'dds-resourcebanner',
|
|
5
|
+
inner: 'dds-resourcebanner__inner',
|
|
6
|
+
panel: 'dds-resourcebanner__panel',
|
|
7
|
+
content: 'dds-resourcebanner__content',
|
|
8
|
+
title: 'dds-resourcebanner__title',
|
|
9
|
+
description: 'dds-resourcebanner__description',
|
|
10
|
+
list: 'dds-resourcebanner__list',
|
|
11
|
+
item: 'dds-resourcebanner__item',
|
|
12
|
+
};
|
|
13
|
+
/** Generated so defaults cannot drift from the contract. */
|
|
14
|
+
export const resourceBannerDefaults = { ground: 'page', headingLevel: 'h2', externalLabel: '(opens in a new tab)', downloadLabel: '(downloads a file)' };
|
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* Scoped to this package, like the generated sheet beside it.
|
|
3
|
+
*
|
|
4
|
+
* `:where([data-dds-context="marketing"])` confines these rules without contributing specificity,
|
|
5
|
+
* so each is decided against the generated rule on its own terms.
|
|
6
|
+
*
|
|
7
|
+
* Nothing here moves. The arrival is block-reveal.css's, which says what happens under reduced
|
|
8
|
+
* motion for every block at once; this sheet adds no transition or animation of its own.
|
|
9
|
+
*/
|
|
10
|
+
|
|
11
|
+
/*
|
|
12
|
+
* One column on a phone: the words, then the links under them.
|
|
13
|
+
*
|
|
14
|
+
* The track is written as `minmax(0, 1fr)` rather than `1fr` so a long link label wraps inside the
|
|
15
|
+
* column instead of widening it — a bare `1fr` has a minimum of its content, and an unbroken URL
|
|
16
|
+
* as a label would push the panel past the page's edge.
|
|
17
|
+
*
|
|
18
|
+
* The column counts are here rather than in the contract because a track list is not a token and
|
|
19
|
+
* not a keyword the contract's static CSS accepts.
|
|
20
|
+
*/
|
|
21
|
+
:where([data-dds-context="marketing"]) .dds-resourcebanner .dds-resourcebanner__panel {
|
|
22
|
+
grid-template-columns: minmax(0, 1fr);
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
/*
|
|
26
|
+
* Two equal columns from the fold, and the links centred in theirs.
|
|
27
|
+
*
|
|
28
|
+
* The reference centres the stack beside the words from this width. It centres each link on its
|
|
29
|
+
* own, which leaves a set of different lengths with a different start edge per row — a column the
|
|
30
|
+
* eye cannot run down. So it is the list that is centred, held to the width of its longest row,
|
|
31
|
+
* and the rows inside it share one start edge: the same place on the panel, read as a list.
|
|
32
|
+
*
|
|
33
|
+
* `48rem` longhand because `var()` is not permitted in a container query condition, and it is the
|
|
34
|
+
* width the rest of this package folds at.
|
|
35
|
+
*/
|
|
36
|
+
@container (min-width: 48rem) {
|
|
37
|
+
:where([data-dds-context="marketing"]) .dds-resourcebanner .dds-resourcebanner__panel {
|
|
38
|
+
grid-template-columns: repeat(2, minmax(0, 1fr));
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
:where([data-dds-context="marketing"]) .dds-resourcebanner .dds-resourcebanner__list {
|
|
42
|
+
justify-self: center;
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
/*
|
|
47
|
+
* At full width the words take two shares to the links' one.
|
|
48
|
+
*
|
|
49
|
+
* The reference's own proportion. The words are read and the links are picked from, so the words
|
|
50
|
+
* get the room; a stack of short labels in half the panel is a column of air with a list in it.
|
|
51
|
+
*/
|
|
52
|
+
@container (min-width: 64rem) {
|
|
53
|
+
:where([data-dds-context="marketing"]) .dds-resourcebanner .dds-resourcebanner__panel {
|
|
54
|
+
grid-template-columns: minmax(0, 2fr) minmax(0, 1fr);
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
/*
|
|
59
|
+
* The link fills its row's height and wraps inside its width.
|
|
60
|
+
*
|
|
61
|
+
* The row is held to size.target.min and is a flex container, so the link stretches to it and is
|
|
62
|
+
* never a smaller target than the rule allows, even where its line is shorter. And a flex item's
|
|
63
|
+
* minimum is its content: without `min-inline-size: 0` a long label would overflow the narrow
|
|
64
|
+
* phone column rather than breaking onto a second line.
|
|
65
|
+
*/
|
|
66
|
+
:where([data-dds-context="marketing"]) .dds-resourcebanner .dds-resourcebanner__item > .dds-link {
|
|
67
|
+
min-inline-size: 0;
|
|
68
|
+
overflow-wrap: anywhere;
|
|
69
|
+
}
|