@deriv-com/dds-marketing 1.0.1 → 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 +420 -0
- 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 +22 -0
- package/.llm/components/ctabannerslider.md +36 -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 +236 -0
- package/.llm/components/illustrationscene.md +229 -0
- package/.llm/components/imagebanner.md +278 -0
- package/.llm/components/landinghero.md +24 -0
- package/.llm/components/navbar.md +1 -1
- package/.llm/components/navbaritem.md +4 -0
- package/.llm/components/pageheader.md +22 -0
- 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 +53 -0
- 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 -0
- package/.llm/digest/ctabannerslider.md +7 -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/illustrationcard.md +46 -0
- package/.llm/digest/illustrationscene.md +50 -0
- package/.llm/digest/imagebanner.md +64 -0
- package/.llm/digest/landinghero.md +7 -0
- package/.llm/digest/navbaritem.md +1 -0
- package/.llm/digest/pageheader.md +4 -0
- 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 +25 -2
- package/.llm/tokens.md +37 -1
- package/AGENTS.md +20 -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.d.ts +1 -1
- package/dist/components/blocks/cta-banner/CtaBanner.js +3 -2
- package/dist/components/blocks/cta-banner/CtaBanner.types.d.ts +6 -0
- package/dist/components/blocks/cta-banner/CtaBanner.types.js +1 -1
- package/dist/components/blocks/cta-banner/cta-banner-impl.css +8 -0
- 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 +10 -5
- package/dist/components/blocks/cta-banner-slider/CtaBannerSlider.types.d.ts +12 -0
- package/dist/components/blocks/cta-banner-slider/CtaBannerSlider.types.js +1 -1
- package/dist/components/blocks/cta-banner-slider/cta-banner-slider-impl.css +8 -0
- 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/landing-hero/LandingHero.d.ts +1 -1
- package/dist/components/blocks/landing-hero/LandingHero.js +4 -3
- package/dist/components/blocks/landing-hero/LandingHero.types.d.ts +7 -3
- 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.d.ts +1 -1
- package/dist/components/blocks/page-header/PageHeader.js +3 -2
- package/dist/components/blocks/page-header/PageHeader.types.d.ts +6 -0
- package/dist/components/blocks/page-header/PageHeader.types.js +1 -1
- package/dist/components/blocks/page-header/page-header-impl.css +10 -0
- 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 +92 -0
- package/dist/components/core/background/Background.d.ts +27 -0
- package/dist/components/core/background/Background.js +45 -0
- package/dist/components/core/background/Background.types.d.ts +39 -0
- package/dist/components/core/background/Background.types.js +11 -0
- package/dist/components/core/background/background-impl.css +760 -0
- package/dist/components/core/background/halftone.d.ts +134 -0
- package/dist/components/core/background/halftone.js +722 -0
- 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-halftone.d.ts +15 -0
- package/dist/components/core/background/use-halftone.js +27 -0
- package/dist/components/core/background/use-offscreen.d.ts +10 -0
- package/dist/components/core/background/use-offscreen.js +30 -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 +14 -0
- package/dist/components/core/background/use-spotlight.js +73 -0
- 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.css +40 -0
- package/dist/components/core/illustration-card/IllustrationCard.d.ts +22 -0
- package/dist/components/core/illustration-card/IllustrationCard.js +82 -0
- package/dist/components/core/illustration-card/IllustrationCard.types.d.ts +23 -0
- package/dist/components/core/illustration-card/IllustrationCard.types.js +8 -0
- package/dist/components/core/illustration-card/illustration-card-impl.css +47 -0
- package/dist/components/core/illustration-scene/IllustrationScene.css +41 -0
- package/dist/components/core/illustration-scene/IllustrationScene.d.ts +14 -0
- package/dist/components/core/illustration-scene/IllustrationScene.js +16 -0
- package/dist/components/core/illustration-scene/IllustrationScene.types.d.ts +32 -0
- package/dist/components/core/illustration-scene/IllustrationScene.types.js +8 -0
- package/dist/components/core/illustration-scene/illustration-scene-impl.css +46 -0
- 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 +51 -0
- package/dist/components/index.js +38 -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 +101 -28
- package/package.json +1 -1
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
'use client';
|
|
2
|
+
import { useCallback, useEffect, useRef, useState } from 'react';
|
|
3
|
+
/**
|
|
4
|
+
* The steps taking their turn under `autoplay`: which step is current, and whether the turn is
|
|
5
|
+
* running.
|
|
6
|
+
*
|
|
7
|
+
* The timing is not here. The current step's rule fills over motion.duration.dwell as a CSS
|
|
8
|
+
* animation, and the turn moves on when that animation ends (`next`), so the bar a reader watches
|
|
9
|
+
* and the step changing are one clock rather than two that drift. Holding the turn is pausing that
|
|
10
|
+
* animation, which is what `playing` is for: the stylesheet pauses the fill wherever it is false.
|
|
11
|
+
*
|
|
12
|
+
* It turns only where every condition for it holds:
|
|
13
|
+
* - `autoplay` is on and there are two steps or more;
|
|
14
|
+
* - the reader has not asked for less motion — asked live, so turning it on mid-visit stops it;
|
|
15
|
+
* - the section is on screen. A turn nobody can see does not run, and starts again where it was;
|
|
16
|
+
* - nothing holds it: a pointer over the section or focus inside it holds it for as long as it
|
|
17
|
+
* lasts, and pressing a step stops it for good — CtaBannerSlider's rule, by way of the WAI
|
|
18
|
+
* carousel pattern: a reader who has chosen a step is reading it. The pointer's way, the
|
|
19
|
+
* keyboard's and a touch screen's, which WCAG 2.2.2 asks for of anything that moves on its own.
|
|
20
|
+
*/
|
|
21
|
+
export function useTurn(count, autoplay) {
|
|
22
|
+
const [current, setCurrent] = useState(0);
|
|
23
|
+
const [seen, setSeen] = useState(false);
|
|
24
|
+
const [still, setStill] = useState(false);
|
|
25
|
+
const [held, setHeld] = useState(false);
|
|
26
|
+
const [stopped, setStopped] = useState(false);
|
|
27
|
+
const section = useRef(null);
|
|
28
|
+
const turning = autoplay && count > 1 && !still && !stopped;
|
|
29
|
+
const playing = turning && seen && !held;
|
|
30
|
+
useEffect(() => {
|
|
31
|
+
if (typeof window.matchMedia !== 'function')
|
|
32
|
+
return undefined;
|
|
33
|
+
const query = window.matchMedia('(prefers-reduced-motion: reduce)');
|
|
34
|
+
const follow = () => setStill(query.matches);
|
|
35
|
+
follow();
|
|
36
|
+
query.addEventListener?.('change', follow);
|
|
37
|
+
return () => query.removeEventListener?.('change', follow);
|
|
38
|
+
}, []);
|
|
39
|
+
useEffect(() => {
|
|
40
|
+
const element = section.current;
|
|
41
|
+
if (!autoplay || element === null || typeof IntersectionObserver === 'undefined')
|
|
42
|
+
return undefined;
|
|
43
|
+
const observer = new IntersectionObserver(([entry]) => setSeen(entry?.isIntersecting ?? false));
|
|
44
|
+
observer.observe(element);
|
|
45
|
+
return () => observer.disconnect();
|
|
46
|
+
}, [autoplay]);
|
|
47
|
+
/** The current step's fill has run: the next step takes over, and the first after the last. */
|
|
48
|
+
const next = useCallback(() => {
|
|
49
|
+
if (count > 0)
|
|
50
|
+
setCurrent((at) => (at + 1) % count);
|
|
51
|
+
}, [count]);
|
|
52
|
+
/** A step pressed: it is current, and the turn stops for good. */
|
|
53
|
+
const choose = useCallback((at) => {
|
|
54
|
+
setCurrent(at);
|
|
55
|
+
setStopped(true);
|
|
56
|
+
}, []);
|
|
57
|
+
/** Spread on the section: what holds the turn. */
|
|
58
|
+
const hold = {
|
|
59
|
+
onPointerEnter: (event) => {
|
|
60
|
+
if (event.pointerType === 'mouse')
|
|
61
|
+
setHeld(true);
|
|
62
|
+
},
|
|
63
|
+
onPointerLeave: (event) => {
|
|
64
|
+
if (event.pointerType === 'mouse')
|
|
65
|
+
setHeld(false);
|
|
66
|
+
},
|
|
67
|
+
onFocus: () => setHeld(true),
|
|
68
|
+
onBlur: (event) => {
|
|
69
|
+
if (!event.currentTarget.contains(event.relatedTarget))
|
|
70
|
+
setHeld(false);
|
|
71
|
+
},
|
|
72
|
+
};
|
|
73
|
+
// A list that shrank under the current step falls back to its first.
|
|
74
|
+
return { current: current < count ? current : 0, turning, playing, next, choose, section, hold };
|
|
75
|
+
}
|
|
@@ -0,0 +1,154 @@
|
|
|
1
|
+
/* GENERATED from stickycards.contract.json. Do not edit. */
|
|
2
|
+
|
|
3
|
+
:where([data-dds-context="marketing"]) .dds-stickycards {
|
|
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-stickycards .dds-stickycards__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
|
+
row-gap: var(--space-heading-content);
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
:where([data-dds-context="marketing"]) .dds-stickycards .dds-stickycards__header {
|
|
25
|
+
display: flex;
|
|
26
|
+
flex-direction: column;
|
|
27
|
+
min-inline-size: 0;
|
|
28
|
+
max-inline-size: var(--size-measure-heading);
|
|
29
|
+
row-gap: var(--space-gap-none);
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
:where([data-dds-context="marketing"]) .dds-stickycards .dds-stickycards__title {
|
|
33
|
+
margin-block: 0;
|
|
34
|
+
text-wrap: balance;
|
|
35
|
+
font-family: var(--font-h2-family);
|
|
36
|
+
font-size: var(--font-h2-size);
|
|
37
|
+
font-weight: var(--font-h2-weight);
|
|
38
|
+
letter-spacing: var(--font-h2-letter-spacing);
|
|
39
|
+
line-height: var(--font-h2-line-height);
|
|
40
|
+
margin-block-end: var(--space-heading-title-description);
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
:where([data-dds-context="marketing"]) .dds-stickycards .dds-stickycards__description {
|
|
44
|
+
margin-block: 0;
|
|
45
|
+
font-family: var(--font-body-md-family);
|
|
46
|
+
font-size: var(--font-body-md-size);
|
|
47
|
+
font-weight: var(--font-body-md-weight);
|
|
48
|
+
letter-spacing: var(--font-body-md-letter-spacing);
|
|
49
|
+
line-height: var(--font-body-md-line-height);
|
|
50
|
+
max-inline-size: var(--size-measure-description);
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
:where([data-dds-context="marketing"]) .dds-stickycards .dds-stickycards__list {
|
|
54
|
+
box-sizing: border-box;
|
|
55
|
+
display: grid;
|
|
56
|
+
inline-size: 100%;
|
|
57
|
+
list-style: none;
|
|
58
|
+
margin-block: 0;
|
|
59
|
+
margin-inline: auto;
|
|
60
|
+
min-inline-size: 0;
|
|
61
|
+
padding: 0;
|
|
62
|
+
row-gap: var(--space-grid-gutter);
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
:where([data-dds-context="marketing"]) .dds-stickycards .dds-stickycards__item {
|
|
66
|
+
display: flex;
|
|
67
|
+
flex-direction: column;
|
|
68
|
+
min-inline-size: 0;
|
|
69
|
+
position: relative;
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
:where([data-dds-context="marketing"]) .dds-stickycards .dds-stickycards__backdrop {
|
|
73
|
+
inset: 0;
|
|
74
|
+
overflow: clip;
|
|
75
|
+
pointer-events: none;
|
|
76
|
+
position: absolute;
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
:where([data-dds-context="marketing"]) .dds-stickycards .dds-stickycards__body {
|
|
80
|
+
box-sizing: border-box;
|
|
81
|
+
display: flex;
|
|
82
|
+
flex: auto;
|
|
83
|
+
flex-direction: column;
|
|
84
|
+
min-block-size: 0;
|
|
85
|
+
min-inline-size: 0;
|
|
86
|
+
gap: var(--space-gap-none);
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
:where([data-dds-context="marketing"]) .dds-stickycards .dds-stickycards__media {
|
|
90
|
+
min-inline-size: 0;
|
|
91
|
+
overflow: clip;
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
:where([data-dds-context="marketing"]) .dds-stickycards .dds-stickycards__image {
|
|
95
|
+
display: block;
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
:where([data-dds-context="marketing"]) .dds-stickycards .dds-stickycards__scrim {
|
|
99
|
+
display: none;
|
|
100
|
+
inset: 0;
|
|
101
|
+
pointer-events: none;
|
|
102
|
+
position: absolute;
|
|
103
|
+
background-color: var(--color-bg-overlay);
|
|
104
|
+
border-radius: var(--radius-surface);
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
:where([data-dds-context="marketing"]) .dds-stickycards[data-ground="page"] {
|
|
108
|
+
background-color: var(--color-bg-page);
|
|
109
|
+
color: var(--color-fg-default);
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
:where([data-dds-context="marketing"]) .dds-stickycards[data-ground="strong"] {
|
|
113
|
+
background-color: var(--color-bg-brand-strong);
|
|
114
|
+
color: var(--color-fg-on-brand-strong);
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
:where([data-dds-context="marketing"]) .dds-stickycards[data-ground="subtle"] {
|
|
118
|
+
background-color: var(--color-bg-page);
|
|
119
|
+
background-image: linear-gradient(var(--color-bg-band-subtle), var(--color-bg-band-subtle));
|
|
120
|
+
color: var(--color-fg-default);
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
:where([data-dds-context="marketing"]) .dds-stickycards[data-layout="compact"] .dds-stickycards__image {
|
|
124
|
+
border-radius: var(--radius-surface-compact);
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
:where([data-dds-context="marketing"]) .dds-stickycards[data-layout="compact"] .dds-stickycards__item {
|
|
128
|
+
min-block-size: var(--size-sticky-cards-compact-min);
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
:where([data-dds-context="marketing"]) .dds-stickycards[data-layout="compact"] .dds-stickycards__list {
|
|
132
|
+
max-inline-size: var(--size-sticky-cards-compact-max);
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
:where([data-dds-context="marketing"]) .dds-stickycards[data-layout="compact"] .dds-stickycards__media {
|
|
136
|
+
border-radius: var(--radius-surface-compact);
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
:where([data-dds-context="marketing"]) .dds-stickycards[data-layout="feature"] .dds-stickycards__image {
|
|
140
|
+
border-radius: var(--radius-none);
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
:where([data-dds-context="marketing"]) .dds-stickycards[data-layout="feature"] .dds-stickycards__item {
|
|
144
|
+
min-block-size: var(--size-sticky-cards-feature-min);
|
|
145
|
+
}
|
|
146
|
+
|
|
147
|
+
:where([data-dds-context="marketing"]) .dds-stickycards[data-layout="feature"] .dds-stickycards__list {
|
|
148
|
+
max-inline-size: var(--size-content-max);
|
|
149
|
+
}
|
|
150
|
+
|
|
151
|
+
:where([data-dds-context="marketing"]) .dds-stickycards[data-layout="feature"] .dds-stickycards__media {
|
|
152
|
+
border-radius: var(--radius-none);
|
|
153
|
+
}
|
|
154
|
+
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
import './StickyCards.css';
|
|
2
|
+
import './sticky-cards-impl.css';
|
|
3
|
+
import '../block-reveal.css';
|
|
4
|
+
import { type StickyCardsProps } from './StickyCards.types.js';
|
|
5
|
+
export type { StickyCardsProps };
|
|
6
|
+
/**
|
|
7
|
+
* A heading over a pile of cards that builds as the page scrolls — the reference design's
|
|
8
|
+
* StickyMarketCards (`layout="compact"`), StickyMarketCardsLottie (the `media` callback) and
|
|
9
|
+
* StickyStackedCards (`layout="feature"`), as one block.
|
|
10
|
+
*
|
|
11
|
+
* The pile is CSS. Each card's place in the list is sticky, a step lower than the one before, and
|
|
12
|
+
* every row of the list is as tall as the tallest card, so the card arriving hides the one under it
|
|
13
|
+
* entirely and leaves only its edge. The reference measured the cards with a script and wrote the
|
|
14
|
+
* tallest height onto each; a grid's equal rows say the same thing before any script runs.
|
|
15
|
+
*
|
|
16
|
+
* The covered card draws back and darkens on a scroll timeline: each card's place names a view
|
|
17
|
+
* timeline, and the card before it runs its drawing back down that timeline — so a card recedes as
|
|
18
|
+
* the *next* one crosses it, which is the reference's own measure (the overlap of the next card
|
|
19
|
+
* over this one) said as a range. The names are per card and set here, inline, because a timeline
|
|
20
|
+
* a sibling reads has to be named uniquely and declared in scope on the list; the stylesheet does
|
|
21
|
+
* the rest. See sticky-cards-impl.css for the ranges and the fallbacks.
|
|
22
|
+
*
|
|
23
|
+
* The cards are records, drawn into Card and CardBody: Card for the fill and the corner, CardBody
|
|
24
|
+
* for the words at the card's inset, and the picture beside them. A record rather than a Card the
|
|
25
|
+
* page composes, because the pile needs to know each card's place — its step, its timeline — and
|
|
26
|
+
* a list of markets or steps is what a content system hands over. The one thing a record cannot
|
|
27
|
+
* carry is a player; `media` is how the page puts one in a card's picture slot.
|
|
28
|
+
*
|
|
29
|
+
* Nothing is hidden from assistive technology. The pile is how the list looks, not what it holds:
|
|
30
|
+
* every card is in the list, in order, at every scroll position.
|
|
31
|
+
*
|
|
32
|
+
* `'use client'` for the arrival, and for `useId`, which names the region by its heading and keeps
|
|
33
|
+
* the timeline names of two piles on one page apart.
|
|
34
|
+
*/
|
|
35
|
+
export declare function StickyCards({ ground, layout, title, description, cards, media, }: StickyCardsProps): import("react").JSX.Element;
|
|
@@ -0,0 +1,153 @@
|
|
|
1
|
+
'use client';
|
|
2
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
3
|
+
import { useEffect, useId, useRef, useState } from 'react';
|
|
4
|
+
import './StickyCards.css';
|
|
5
|
+
import './sticky-cards-impl.css';
|
|
6
|
+
import '../block-reveal.css';
|
|
7
|
+
import { given } from '../../given.js';
|
|
8
|
+
import { Card } from '../../core/card/Card.js';
|
|
9
|
+
import { CardBody } from '../../core/card-body/CardBody.js';
|
|
10
|
+
import { arriving, useReveal } from '../use-reveal.js';
|
|
11
|
+
import { stickyCardsDefaults, stickyCardsParts } from './StickyCards.types.js';
|
|
12
|
+
/**
|
|
13
|
+
* How many edges the pile shows at most — the reference design's four.
|
|
14
|
+
*
|
|
15
|
+
* Only the last four cards step down by space.pile.peek; every card before them takes the first
|
|
16
|
+
* card's place, so in a long set the earliest are covered whole rather than adding a fifth, sixth
|
|
17
|
+
* and seventh strip until the pile is taller than the card on top of it.
|
|
18
|
+
*/
|
|
19
|
+
const MOST_EDGES = 4;
|
|
20
|
+
/** A card's step down the pile: 0 for the first of the last four and everything before it. */
|
|
21
|
+
const depthOf = (at, count) => Math.max(0, at - Math.max(0, count - MOST_EDGES));
|
|
22
|
+
/** Nothing a `media` callback can return that would draw something. */
|
|
23
|
+
const drawn = (node) => node !== undefined && node !== null && node !== false && node !== '';
|
|
24
|
+
/**
|
|
25
|
+
* A heading over a pile of cards that builds as the page scrolls — the reference design's
|
|
26
|
+
* StickyMarketCards (`layout="compact"`), StickyMarketCardsLottie (the `media` callback) and
|
|
27
|
+
* StickyStackedCards (`layout="feature"`), as one block.
|
|
28
|
+
*
|
|
29
|
+
* The pile is CSS. Each card's place in the list is sticky, a step lower than the one before, and
|
|
30
|
+
* every row of the list is as tall as the tallest card, so the card arriving hides the one under it
|
|
31
|
+
* entirely and leaves only its edge. The reference measured the cards with a script and wrote the
|
|
32
|
+
* tallest height onto each; a grid's equal rows say the same thing before any script runs.
|
|
33
|
+
*
|
|
34
|
+
* The covered card draws back and darkens on a scroll timeline: each card's place names a view
|
|
35
|
+
* timeline, and the card before it runs its drawing back down that timeline — so a card recedes as
|
|
36
|
+
* the *next* one crosses it, which is the reference's own measure (the overlap of the next card
|
|
37
|
+
* over this one) said as a range. The names are per card and set here, inline, because a timeline
|
|
38
|
+
* a sibling reads has to be named uniquely and declared in scope on the list; the stylesheet does
|
|
39
|
+
* the rest. See sticky-cards-impl.css for the ranges and the fallbacks.
|
|
40
|
+
*
|
|
41
|
+
* The cards are records, drawn into Card and CardBody: Card for the fill and the corner, CardBody
|
|
42
|
+
* for the words at the card's inset, and the picture beside them. A record rather than a Card the
|
|
43
|
+
* page composes, because the pile needs to know each card's place — its step, its timeline — and
|
|
44
|
+
* a list of markets or steps is what a content system hands over. The one thing a record cannot
|
|
45
|
+
* carry is a player; `media` is how the page puts one in a card's picture slot.
|
|
46
|
+
*
|
|
47
|
+
* Nothing is hidden from assistive technology. The pile is how the list looks, not what it holds:
|
|
48
|
+
* every card is in the list, in order, at every scroll position.
|
|
49
|
+
*
|
|
50
|
+
* `'use client'` for the arrival, and for `useId`, which names the region by its heading and keeps
|
|
51
|
+
* the timeline names of two piles on one page apart.
|
|
52
|
+
*/
|
|
53
|
+
export function StickyCards({ ground = stickyCardsDefaults.ground, layout = stickyCardsDefaults.layout, title, description, cards, media, }) {
|
|
54
|
+
const titleId = useId();
|
|
55
|
+
const [band, revealed] = useReveal();
|
|
56
|
+
// The preview's bare view and a content system that has not loaded both hand over nothing; the
|
|
57
|
+
// heading alone is the honest drawing of an empty set.
|
|
58
|
+
const set = Array.isArray(cards) ? cards : [];
|
|
59
|
+
/*
|
|
60
|
+
Whether the tallest card fits the window below the bar, where the pile pins it. One that does
|
|
61
|
+
not would be covered before its foot was ever on screen — words a reader cannot reach — and a
|
|
62
|
+
translation is what makes a card that tall: German runs a third longer than the English the
|
|
63
|
+
pile was drawn for. The stylesheet pins nothing while this says so, and every card shows in full.
|
|
64
|
+
|
|
65
|
+
Measured rather than guessed, because only the browser knows how tall the words came out. Every
|
|
66
|
+
row is the tallest card's height, so the list's first item is the measure. Starts false, so the
|
|
67
|
+
server's HTML and the first render agree and a reader with no script still gets the pile.
|
|
68
|
+
*/
|
|
69
|
+
const list = useRef(null);
|
|
70
|
+
const [tall, setTall] = useState(false);
|
|
71
|
+
/*
|
|
72
|
+
The heading's height and the gap under it, once measured: the heading pins above the pile and
|
|
73
|
+
each card stops this much lower, so the cards gather under it rather than over it. Undefined
|
|
74
|
+
until then, and the heading does not pin without it — on a server render, or with no script, the
|
|
75
|
+
cards would otherwise come to rest on top of the words.
|
|
76
|
+
*/
|
|
77
|
+
const [head, setHead] = useState(undefined);
|
|
78
|
+
/*
|
|
79
|
+
How far below the heading the card on top reaches — the gap and one card's height. The heading
|
|
80
|
+
carries it as a margin, so it is held only while that much of the list is still to come, and
|
|
81
|
+
lets go at the moment the top card does: the two then scroll up as one, rather than the heading
|
|
82
|
+
staying behind for the cards to scroll up over it. The edges peeking under the top card do not
|
|
83
|
+
count: they close up into it before it moves.
|
|
84
|
+
*/
|
|
85
|
+
const [tail, setTail] = useState(undefined);
|
|
86
|
+
useEffect(() => {
|
|
87
|
+
const element = list.current;
|
|
88
|
+
if (element === null || typeof ResizeObserver === 'undefined')
|
|
89
|
+
return undefined;
|
|
90
|
+
const measure = () => {
|
|
91
|
+
const item = element.firstElementChild;
|
|
92
|
+
if (item === null)
|
|
93
|
+
return;
|
|
94
|
+
const style = getComputedStyle(element);
|
|
95
|
+
const px = (name) => Number.parseFloat(style.getPropertyValue(name)) || 0;
|
|
96
|
+
const header = element.parentElement?.querySelector(`:scope > .${stickyCardsParts.header}`);
|
|
97
|
+
const under = header === null || header === undefined
|
|
98
|
+
? 0
|
|
99
|
+
: header.offsetHeight + (Number.parseFloat(getComputedStyle(element.parentElement).rowGap) || 0);
|
|
100
|
+
setHead(under);
|
|
101
|
+
const gap = Number.parseFloat(getComputedStyle(element.parentElement).rowGap) || 0;
|
|
102
|
+
setTail(gap + item.offsetHeight);
|
|
103
|
+
// The pinned top, the heading pinned above it, and the four edges a pile can show.
|
|
104
|
+
const top = px('--size-bar-height') + px('--space-inset-page') + under + 4 * px('--space-pile-peek');
|
|
105
|
+
setTall(item.getBoundingClientRect().height + top > window.innerHeight);
|
|
106
|
+
};
|
|
107
|
+
measure();
|
|
108
|
+
const observer = new ResizeObserver(measure);
|
|
109
|
+
observer.observe(element);
|
|
110
|
+
window.addEventListener('resize', measure);
|
|
111
|
+
return () => {
|
|
112
|
+
observer.disconnect();
|
|
113
|
+
window.removeEventListener('resize', measure);
|
|
114
|
+
};
|
|
115
|
+
}, []);
|
|
116
|
+
// A dashed ident for each card's timeline. `useId` returns `:r1:`-style ids, which are not valid
|
|
117
|
+
// in an ident, so only the letters and digits are kept.
|
|
118
|
+
const scope = `--dds-stickycards-${titleId.replace(/[^a-zA-Z0-9]/g, '')}`;
|
|
119
|
+
const nameAt = (at) => `${scope}-${at}`;
|
|
120
|
+
/*
|
|
121
|
+
What each card's picture slot holds, worked out once for the whole pile. A pile is one set, so
|
|
122
|
+
it takes one arrangement: the words-only arrangement — title beside sentence, in the middle of
|
|
123
|
+
the card — only when no card in it has a picture. A pile where some do keeps every card's words
|
|
124
|
+
stacked at the top, so a card without a picture reads as one of the set rather than a different
|
|
125
|
+
kind of card.
|
|
126
|
+
*/
|
|
127
|
+
const slots = set.map((card, at) => {
|
|
128
|
+
const player = media?.(card, at);
|
|
129
|
+
const hasPlayer = drawn(player);
|
|
130
|
+
const image = hasPlayer ? undefined : card.image;
|
|
131
|
+
const hasImage = image !== undefined && given(image.src);
|
|
132
|
+
return { player, hasPlayer, image, hasImage };
|
|
133
|
+
});
|
|
134
|
+
const pictured = slots.some((slot) => slot.hasPlayer || slot.hasImage);
|
|
135
|
+
return (_jsx("section", { className: stickyCardsParts.root, "data-ground": ground, "data-layout": layout, "data-pile": pictured ? 'pictured' : 'words', "data-head-pinned": head === undefined ? undefined : 'true',
|
|
136
|
+
// On the section, where the heading and the list under it both read it.
|
|
137
|
+
style: tail === undefined ? undefined : { '--dds-stickycards-tail': `${tail}px` }, "aria-labelledby": titleId, children: _jsxs("div", { className: stickyCardsParts.inner, ref: band, "data-revealed": revealed, children: [_jsxs("div", { className: stickyCardsParts.header, children: [_jsx("h2", { className: stickyCardsParts.title, id: titleId, ...arriving(0), children: title }), given(description) ? (_jsx("p", { className: stickyCardsParts.description, ...arriving(1), children: description })) : null] }), _jsx("ul", { ref: list, className: stickyCardsParts.list, "data-tall": tall || undefined, role: "list", style: set.length > 0
|
|
138
|
+
? {
|
|
139
|
+
'--dds-stickycards-scope': set.map((_, at) => nameAt(at)).join(', '),
|
|
140
|
+
...(head === undefined ? {} : { '--dds-stickycards-head': `${head}px` }),
|
|
141
|
+
}
|
|
142
|
+
: undefined, children: set.map((card, at) => {
|
|
143
|
+
const { player, hasPlayer, image, hasImage } = slots[at];
|
|
144
|
+
const depth = depthOf(at, set.length);
|
|
145
|
+
const next = at + 1 < set.length ? depthOf(at + 1, set.length) : depth;
|
|
146
|
+
return (_jsxs("li", { className: stickyCardsParts.item, "data-media": hasPlayer ? 'node' : hasImage ? 'image' : 'none', style: {
|
|
147
|
+
'--dds-stickycards-depth': depth,
|
|
148
|
+
'--dds-stickycards-next-depth': next,
|
|
149
|
+
'--dds-stickycards-own': nameAt(at),
|
|
150
|
+
...(at + 1 < set.length ? { '--dds-stickycards-next': nameAt(at + 1) } : {}),
|
|
151
|
+
}, children: [_jsxs(Card, { variant: card.variant ?? 'accent-strong', children: [layout === 'compact' && card.background && given(card.background.src) ? (_jsx("span", { className: stickyCardsParts.backdrop, children: _jsx("img", { src: card.background.src, alt: card.background.alt, width: card.background.width, height: card.background.height, loading: "lazy", decoding: "async" }) })) : null, _jsxs("div", { className: stickyCardsParts.body, children: [_jsx(CardBody, { title: card.title, description: card.description }), hasPlayer || hasImage ? (_jsx("div", { className: stickyCardsParts.media, children: hasPlayer ? (player) : (_jsx("img", { className: stickyCardsParts.image, src: image.src, alt: image.alt, width: image.width, height: image.height, loading: "lazy", decoding: "async" })) })) : null] })] }), _jsx("span", { className: stickyCardsParts.scrim })] }, `${card.title}-${at}`));
|
|
152
|
+
}) })] }) }));
|
|
153
|
+
}
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
import type { StickyCardsItem } from '../../sticky-cards-data.js';
|
|
2
|
+
export interface StickyCardsOwnProps {
|
|
3
|
+
/**
|
|
4
|
+
* `page` — The default, and the page's own white. The reference design's sticky stacked cards sit on it
|
|
5
|
+
* `subtle` — A quiet step off the page — the reference design's slate band, which its market cards sit on. Painted as the band's tint laid over the page's own ground; the light and dark cards are raised a step so their edges do not sink into it, FeatureCards' answer
|
|
6
|
+
* `strong` — `color.bg.brand-strong`, the dark band, for a section a reader should arrive at. The heading turns white; a dark card on it is told apart by its edge in the pile more than by its fill, so alternate the cards
|
|
7
|
+
*/
|
|
8
|
+
ground?: 'page' | 'subtle' | 'strong';
|
|
9
|
+
/**
|
|
10
|
+
* `compact` — The default — the reference design's StickyMarketCards and their animation sibling. Cards held to the heading's measure, at least size.sticky-cards.compact-min tall, the title at the card's own step: a photograph behind the card where it has a `background`, and a landscape container beside the words from the fold — under them on a phone — for its `image` or the page's player. With neither, the title beside its sentence. Any number of cards, three or more; past four, the earliest share an edge so no more than four ever show
|
|
11
|
+
* `feature` — The reference design's StickyStackedCards — about three large cards, each the width of the page and at least size.sticky-cards.feature-min tall, the title at the h3 step, its words beside a picture that runs to the card's edges and fills its half from the fold, under them on a phone. Give every card an `image` or a `media`: a card here without one is words beside an empty half
|
|
12
|
+
*/
|
|
13
|
+
layout?: 'compact' | 'feature';
|
|
14
|
+
/** Always. What the set is, in the fewest words — "What we offer", "Start trading in minutes". It names the section as a region, so a screen reader can jump to it and past it. */
|
|
15
|
+
title: string;
|
|
16
|
+
/** A line saying what the cards have in common, when the title alone does not. */
|
|
17
|
+
description?: string;
|
|
18
|
+
/** Always. The cards, in the order the reader meets them — the first is the first one covered, the last ends the pile on top. Each has a title, a sentence, a fill (`variant`), and where it has them an `image` — the card's container in `compact`, its half in `feature` — and in `compact` a `background` photograph under the card's wash. Every card is drawn the height of the tallest, so the pile covers cleanly: keep the descriptions about the same length. An empty list draws the heading alone. A picture on every card or on none: a pile is one set, and it takes one arrangement — words beside the picture, or, where no card has one, each title beside its sentence. A card left without a picture in a pile of pictured cards keeps its words stacked at the top like the rest, beside an empty half. */
|
|
19
|
+
cards: StickyCardsItem[];
|
|
20
|
+
/** A card shows something the page plays itself — a Lottie animation, a video — in the place its picture would take, the reference design's StickyMarketCardsLottie. Given each card and its place in the list, return the player for that card, or nothing to fall back to the card's `image`. The block ships no player of its own and imports none: the page mounts its own. The slot is the picture's place — beside the words from the fold, under them on a phone — and the player should fill it: landscape in `compact`, the whole half in `feature`. */
|
|
21
|
+
media?: (card: StickyCardsItem, index: number) => import('react').ReactNode;
|
|
22
|
+
}
|
|
23
|
+
export type StickyCardsProps = StickyCardsOwnProps;
|
|
24
|
+
/** The class each part carries. Apply these — do not retype them. */
|
|
25
|
+
export declare const stickyCardsParts: {
|
|
26
|
+
readonly root: "dds-stickycards";
|
|
27
|
+
readonly inner: "dds-stickycards__inner";
|
|
28
|
+
readonly header: "dds-stickycards__header";
|
|
29
|
+
readonly title: "dds-stickycards__title";
|
|
30
|
+
readonly description: "dds-stickycards__description";
|
|
31
|
+
readonly list: "dds-stickycards__list";
|
|
32
|
+
readonly item: "dds-stickycards__item";
|
|
33
|
+
readonly backdrop: "dds-stickycards__backdrop";
|
|
34
|
+
readonly body: "dds-stickycards__body";
|
|
35
|
+
readonly media: "dds-stickycards__media";
|
|
36
|
+
readonly image: "dds-stickycards__image";
|
|
37
|
+
readonly scrim: "dds-stickycards__scrim";
|
|
38
|
+
};
|
|
39
|
+
/** Generated so defaults cannot drift from the contract. */
|
|
40
|
+
export declare const stickyCardsDefaults: {
|
|
41
|
+
readonly ground: "page";
|
|
42
|
+
readonly layout: "compact";
|
|
43
|
+
};
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
// GENERATED from sticky-cards.contract.json. Do not edit.
|
|
2
|
+
/** The class each part carries. Apply these — do not retype them. */
|
|
3
|
+
export const stickyCardsParts = {
|
|
4
|
+
root: 'dds-stickycards',
|
|
5
|
+
inner: 'dds-stickycards__inner',
|
|
6
|
+
header: 'dds-stickycards__header',
|
|
7
|
+
title: 'dds-stickycards__title',
|
|
8
|
+
description: 'dds-stickycards__description',
|
|
9
|
+
list: 'dds-stickycards__list',
|
|
10
|
+
item: 'dds-stickycards__item',
|
|
11
|
+
backdrop: 'dds-stickycards__backdrop',
|
|
12
|
+
body: 'dds-stickycards__body',
|
|
13
|
+
media: 'dds-stickycards__media',
|
|
14
|
+
image: 'dds-stickycards__image',
|
|
15
|
+
scrim: 'dds-stickycards__scrim',
|
|
16
|
+
};
|
|
17
|
+
/** Generated so defaults cannot drift from the contract. */
|
|
18
|
+
export const stickyCardsDefaults = { ground: 'page', layout: 'compact' };
|